Before we go into optional types, there’s a concept to be clear about: type safety. What is type safety? This type cannot be assigned a value of another type. For example, a string variable may not be assigned an int value. Is OC type safe? No, for example, many objects can be given nil, which is giving other types.

In OC, if we want to determine whether a value has valid values, we usually use nil, but the scope of nil is limited to most objects. For struct and other types, we also need to determine whether NSNotFound and so on

Based on this, the Swift syntax has been modified to provide optional types, which are more like a collection, indicating that instances of this class belong to one of {class, nil}. Swift is a type-safe language, so an object can either belong to a class or it can belong to nil, so we can’t assign nil to an Int, but we can assign nil to an Optional Int

The source code here also confirms our speculation that Optional is an enum collection

// swift/stdlib/public/core/Optional.swift public enum Optional : Case none case some(Wrapped) // Public init(_ some:) Wrapped) public func map(_ transform: (Wrapped) throws -> U) rethrows -> U? public func flatMap(_ transform: (Wrapped) throws -> U?) rethrows -> U? public init(nilLiteral: ()) public var unsafelyUnwrapped: Wrapped { get } }Copy the code

Nil assigns to an optional type

var code = 4
code = nil //error  'nil' cannot be assigned to type 'Int'

var code: Int? = 4
code = nil
Copy the code

Another special note: in OC, nil indicates that the object points to a nonexistent object, whereas in Swift, nil indicates that the object is missing a valid value. I understand that Swift still uses nil for OC compatibility, but I think it’s easier to use Undefined in JS.

Forced resolution (assignment of optional types to non-optional types)

In Swift, assigning an optional type directly to a non-optional type is an error. If we confirm that the optional type has a value, we can force the resolution to assign the value, and force the resolution to increment directly after the instance of the optional type! Can be

let string1: String? = "abc" let string2: String = string1 //error Value of optional type 'String? ' must be unwrapped to a value of type 'String' let string1: String? = "abc" let string2: String = string1! //correctCopy the code

The second version compiles successfully, but since it may crash at runtime, swift documentation recommends checking before assigning, i.e. :

let string1: String? = "abc" if string1 ! = nil { //best practice let string2: String = string1! print(string2) }Copy the code

Optional binding

In OC, if we want to determine that the argument is not nil, this is what we usually do

if (a ! = nil && b ! = nil){ //case }Copy the code

With optional types, Swift brings a more elegant way of writing

if let a1 = a, let b1 = b { // equal to (a ! = nil && b ! = nil) }Copy the code

In addition, when determining whether a value is empty in OC or JS, it is often necessary to determine whether the upper layer of the class has a value, otherwise it is easy to crash

if (person && person.homeInfo && person.homeInfo.adress){

}
Copy the code

We can solve this in Swift using an optional chain call

let adress = person? .homeInfo? .adress { }Copy the code

Implicitly resolves optional types

If we know that an optional type actually has a value, then it’s kind of redundant to keep judging nil and then assigning to it. Swift also introduced implicit resolution, which in plain English says: even though you’re declaring an optional type, I know that you actually have a value, so I’m going to use you as a valued type

For example:

// possibleString: String? = "An optional string." let forcedString: String = possibleString! // Let assumedString: String! = "An IMPLICITLY unwrapped optional string." let implicitString: string = assumedString // No exclamation mark requiredCopy the code

Other grammatical sugars

In the ES6, provides the following syntactic sugar, if the object is undefined, then use other defaults let string = a | | ‘string value’

Swift references this, but instead of two question marks??

let a = string ?? "string value"
Copy the code

Why did SWIFT design optional types

  1. Swift is a type-safe language that requires optional types to be compatible with OC and provides a state of missing values, similar to undefined
  2. Optional types bring a more powerful and elegant way of writing and syntactic sugar for determining nil

reference

Swiftgg. Gitbook. IO/swift/swift…