简体   繁体   English

Swift中的两个(或更多)选项

[英]Two (or more) optionals in Swift

While watching an Apple's video about LLDB debugger I found something I can't find an explanation for; 在观看Apple关于LLDB调试器的视频时,我发现了一些我无法找到解释的内容; he was talking about optional values when he wrote: 当他写道时,他正在谈论可选值:

var optional: String? = nil; //This is ok, a common optional
var twice_optional: String?? = nil; //What is this and why's this useful??

I opened a playground and started trying it out and realized that you can write as many as ? 我打开一个游乐场,开始尝试,并意识到你可以写多少? as you want, and then unwrap them with the same number of ! 如你所愿,然后用相同的数量打开它们! . I understand the concept of wrapping/unwrapping a variable but can't think of a situation where I would like to wrap a value 4, 5 or 6 times. 我理解包装/解包变量的概念,但不能想到我想要包装值4,5或6次的情况。

(Updated for Swift >=3) (更新为Swift> = 3)

"Double optionals" can be useful, and the Swift blog entry "Optionals Case Study: valuesForKeys" describes an application. “双选项”可能很有用,Swift博客条目“Optionals Case Study:valuesForKeys”描述了一个应用程序。

Here is a simplified example: 这是一个简化的例子:

let dict : [String : String?] = ["a" : "foo" , "b" : nil]

is a dictionary with optional strings as values. 是一个字典,可选字符串作为值。 Therefore 因此

let val = dict[key]

has the type String?? String??类型String?? aka Optional<Optional<String>> . aka Optional<Optional<String>> It is .none (or nil ) if the key is not present in the dictionary, and .some(x) otherwise. 如果密钥不在字典中,则为.none (或nil ),否则为.some(x) In the second case, x is a String? 在第二种情况下, x是一个String? aka Optional<String> and can be .none (or nil ) or .some(s) where s is a String. aka Optional<String> ,可以是.none (或nil )或.some(s) ,其中s是String。

You can use nested optional binding to check for the various cases: 您可以使用嵌套的可选绑定来检查各种情况:

for key in ["a", "b", "c"] {

    let val = dict[key]
    if let x = val {
        if let s = x {
            print("\(key): \(s)")
        } else {
            print("\(key): nil")
        }
    } else {
        print("\(key): not present")
    }

}

Output: 输出:

a: foo
b: nil
c: not present

It might be instructive to see how the same can be achieved with pattern matching in a switch-statement: 看看在switch语句中如何通过模式匹配实现同样的效果可能是有益的:

let val = dict[key]
switch val {
case .some(.some(let s)):
    print("\(key): \(s)")
case .some(.none):
    print("\(key): nil")
case .none:
    print("\(key): not present")
}

or, using the x? 或者,使用x? pattern as a synonym for .some(x) : pattern作为.some(x)的同义词:

let val = dict[key]
switch val {
case let (s??):
    print("\(key): \(s)")
case let (s?):
    print("\(key): nil")
case nil:
    print("\(key): not present")
}

(I do not know a sensible application for more deeply nested optionals.) (我不知道更深层嵌套的选项的合理应用。)

var tripleOptional: String???

is same as 和...一样

var tripleOptional: Optional<Optional<Optional<String>>>

I cannot think of any useful use of it, but its there because optionals are generic work for any type of object. 我想不出它的任何有用用途,但它的存在是因为选项是任何类型对象的通用工作。 Nested optionals are like box put into another box or array but into an other array. 嵌套的选项就像放入另一个盒子或数组但放入另一个数组的盒子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM