We have been using swift as the new programming language for Apple for some time. One of the great advantages is what Apple calls "optional types". Almost all objective-c programmers know that using nil to represent an object of a reference type has no value. But it is still a bit farfetched to associate nil with the type of a variable.
Here, let's introduce the optional type (optional type) provided by Swift. Introduce some of the implementation details, and then point out several points in the optional type system.
Type?
Before we get into the code, let's see why a type is defined as optional. The types we encounter are generally generic, non-optional types. Includes general value types, such as Int,bool and string. There are also reference types for complex points, such as UIView, and so on.
When we declare these types of variables, Swift requires that these variables be assigned values. This requirement is very strict, if you want to use it before initializing a variable to make it compile.
The surface looks depressed, but it really helps. In the long run, by not allowing this code to compile, Swift avoids potential run-time errors caused by the use of uninitialized values.
Let X:int = Nil
However, one would attempt to assign a value of nil to a let declaration.
Such code throws an error directly: the type "INT" is not protocol ' nilliteralconvertible ' type. For types that are non-optional type, the "nilliteralconvertible" protocol is not implemented without the ability to initialize with nil. So, a simple x, just an instance of an int, can only be assigned a value of int instead of nil.
The variables in the program cannot all have initial values, so this time optional type should be out. Swift, as long as a question mark is added to the back of any type, it becomes the optional type (controllable). For example, in the previous example. Just add a question mark to the int and you can assign the X to nil.
This should be a lot of OBJECTIVE-C's buddies need. The value of a variable can be either an "actual" value or nil. It only depends on what kind of situation your code is dealing with.
Packing
You might say, "int is just a value type, not an object how can I use nil?" Nsinteger can't be used so much. ”
Indeed, you are right. Nsinteger has no nil value. Or more accurately, you get an integer value of 0 after the type conversion. So, in the Objective-c API defines a lot of tags indicating "no value" status: 0,1,nsintergermin,nsintegermax and Nsnotfound, etc., all indicate "nothing".
When you think about it, you will find that there is no consistent way to indicate the value of nothing, but to mark "nothing" with a different custom value adds a certain degree of complexity. Take a value that does not exist in an array to return the thing Nsnotfound, take a row that does not exist in the table view, returns the thing one-1.
Swift's optional type provides a clearer way to represent. But how do you make any type have the optional type function? These are built on the basis of generics:
Above is the definition of the Swift Core library for optional type (slightly modified). Swift defines a new type of optional, which consists of two values, one is "Nothing", is called none, and the other is a value that wraps the value of a type T. Swift is using this mechanism to wrap up a value of a certain type, which can be either empty (nothing) or empty.
In this example, the first integer is just a value of type int. The following type followed by a question mark "? "In fact, they are all optional<t> types. Or, a short can be expressed as an int?.
With this ability, Swift can give a value of "nothing" to any type of nil, even if it is an int. The Optional type can also represent a value of "real" or a value of "nothing" without the need for other special values.
Unpacking
This means that optional value also raises a problem. Now we know that the Optional type is a standalone types:optional<t>. Therefore, where T is required, it is not possible for a function to pass in a parameter of type T, so the value of optional<t> is not available:
We need to take the required value out of the optional box. And, it's important to check if the value exists before that. Swift offers an exclamation mark! " operator to extract the value.
Remember to change the value of X to 100 instead of the previous nil. Because, the exclamation mark operator only applies to the value of optional type, which itself has a "real" value. If not, it throws a run-time exception.
Therefore, before unpacking the value, we need to determine whether this optional (optional) value is empty. is similar to what we often do in objective-c.
But what if this x comes back from another method? We can call this function directly to verify the return value, without having to assign a value to the local variable first, and then detect if it is empty.
Swift has implemented this function, called optional binding (optional binding). Using the IF and let two keywords, you can write a line of compact code to detect whether a function return value exists.
Here we have not used the exclamation-point operator to display the forced unboxing. This is another handy place for optional binding (optional bindings). Simply unpacking the optional type (optional type) in the decision expression of the IF statement, you can determine if the optional type has a value and do not use the exclamation-mark operator manually to remove the box.
Chaining
Now we establish an accurate rule for detecting and unpacking optional value (optional value). For example, how do I invoke a method on optional value? You're sure to call the method on a potentially empty object, which is certain to happen. In Objective-c, calling a method on a nil object returns a nil.
Fortunately Swift can do the same. Use optional chaining (optional chain) to invoke methods that may be empty (nil) :
Insert a question mark between the object and the method it calls "? operator, we can show whether we want a value that actually exists or a "nothing". This is very similar to the OBJECTIVE-C call.
Note: The return value of the called method must be optional type (optional), even if the return value of the method is defined as a non-optional type (non-optional). Therefore, the return value at any point on the method chain that is called on the optional value (optional value) is optional. Be sure to consider the possibility that the value may be empty when handling the return value.
Consider the following code:
The SomeMethod () method declares that the return value is int, and z still gets a optional value (optional). Because, we use the optional chaining (optional chain) to invoke the method. This may seem a bit confusing, but it's helpful. Especially when optional binding (optional bindings). For example, if let z = y in the above code? An somemethod () expression.
This can be very concise to deal with the problem:
- If Y is nil (here is nil), optional chaining (optional chain) can guarantee that we write the code without error.
- If Y is nil or the SomeMethod () method returns the nil,optional binding (optional binding), nil is not assigned to non-optional value (not optional) Z.
- Eventually we'll get Z, but we don't have to manually remove the box. Because this is an optional binding (optional binding).
In summary, Swift provides a very clear system for handling nil values. We may have extra type safety, avoid unnecessary special defined values, and be as concise as objective-c.
Welcome Dabigatran to learn from each other and make progress together. QQ Group: 58099570 | To be kind, reprint please indicate the source!
Optional types of Swift