The optional type is a new and powerful feature in Swift. In this article, Bovenri discusses how to ensure strong type security through optional types in swift. As an example, let's create a swift version of the Objective-c API, but in fact Swift does not need such APIs in itself.
Add Objectsforkeys function for dictionary
In Objective-c, Nsdictionary has a method-objectsforkeys:nofoundmarker: This method requires a Nsarray array as the key value parameter, and then returns an array containing the related values. The document reads: "Returns the nth value in the array, corresponding to the nth value in the input array," if there is a key value that does not exist in the dictionary? So there is a notfoundmarker as a return hint. For example, if the third key value is not found, then the third value in the return array is this notfoundmarker, not the third value in the dictionary, but this value is used only to remind the original dictionary that the corresponding value is not found, but that element exists in the returned array. and using Notfoundmarker as a placeholder because this object cannot be used directly, there is a special class in the foundation framework that handles this: Nsnull.
In Swift, the dictionary class does not have a function like Objectsforkeys, and in order to illustrate the problem, we add one and make it a common way to manipulate the dictionary values. We can use extension to achieve:
Copy Code code as follows:
Extension dictionary{
Func Valuesforkeys (Keys:[k], notfoundmarker:v)->[v]{
The implementation code will be written later
}
}
This is the SWIFT version we have implemented, which is quite different from the objective-c version. In Swift, because of its strongly-typed reason that the returned array of results can contain only a single type of element, we cannot put nsnull in a string array, but Swift has a better choice, and we can return an optional type of data. All of our values are sealed in optional types, not nsnull, and we'll just use nil.
Copy Code code as follows:
Extension dictionary{
Func Valuesforkeys (keys: [Key])-> [Value?] {
var result = [Value?] ()
Result.reservecapacity (Keys.count)
For key in keys{
Result.append (Self[key])
}
return result
}
}
A simpler approach in Swift
Small partners may ask why it is not necessary to implement such an API in Swift? In fact, it has a simpler implementation, as shown in the following code:
Copy Code code as follows:
Extension Dictionary {
Func Valuesforkeys (keys: [Key])-> [Value?] {
Return Keys.map {self[$0]}
}
}
The functionality implemented in this manner is the same as the first method implementation, although the core function is to encapsulate the call of the map, and this example illustrates why Swift does not provide lightweight API interfaces because the small partners simply call the map to implement it.
Next, we'll experiment with a few examples:
Copy Code code as follows:
var dic:dictionary = ["1": 2, "3": 3, "4": 5]
var t = Dic.valuesforkeys (["1", "4"])
The results are: [Optional (2), Optional (5)]
var t = Dict.valuesforkeys (["3", "9"])
The result is: [Optional (3), nil]
t = Dic.valuesforkeys ([])
The result is: []
Inline optional type
Now, if we call the last method for each result, look at the result?
Copy Code code as follows:
var dic:dictionary = ["1": 2, "3": 3, "4": 5]
var t = Dic.valuesforkeys (["1", "4"]). Last//Result: Optional (Optional (5))
Optional (Optional ("Ching"))
var t = Dict.valuesforkeys (["3", "9"]). Last
The result is: Optional (nil)
var t = Dict.valuesforkeys ([]). Last
The result is: nil
The small partners are immediately confused, why are there two layers of optional types? , especially for the second case of optional (nil), what is this rhythm?
Let's look back at the definition of the last attribute:
Copy Code code as follows:
Obviously the type of the last property is an optional type of the array element type, in which case the element type is (string), then the returned type is combined, so the result is String?? , which is called the nested optional type. But what does the nature of nested optional types mean?
If you recall the above method in Objective-c, we will use Nsnull as a placeholder, and the objective-c invocation syntax looks like this:
Copy Code code as follows:
[Dict valuesforkeys:@[@ "1", @ "4"] notfoundmarker:[nsnull Null]].lastobject
5
[Dict valuesforkeys:@[@ "1", @ "3"] notfoundmarker:[nsnull Null]].lastobject
Nsnull
[Dict valuesforkeys:@[] Notfoundmarker:[nsnull null]].lastobject
Nil
Either the swift version or the objective-c version, the return value of nil means that the array is empty, so it has no last element. But if the return is optional (nil) or the Nsnull in objective-c indicates that the last element in the array exists, the contents of the element are empty. This can only be achieved with the help of nsnull as placeholders in objective-c, but Swift is able to implement the language system type perspective.
provide a default value
Further encapsulation, what if one or some of the elements in my dictionary do not exist and we want to provide a default value? The implementation method is simple:
Copy Code code as follows:
Extension Dictionary {
Func Valuesforkeys (Keys:[key], notfoundmarker:value)->[value]{
Return Self.valueforkeys (KES). map{$? Notfoundmarker}
}
}
Dict.valuesforkeys (["1", "5"], Notfoundmarker: "Anonymous")
Compared with objective-c, it requires placeholders for placeholder purposes, but Swift has already supported this usage from the level of the language type system, while providing rich grammatical functionality. This is the strength of Swift's optional type. Also note that the above example uses the null-fitting operator??。