While watching an Apple's video about LLDB debugger I found something I can't find an explanation for; he was talking about optional values when he wrote:
在观看苹果关于LLDB调试器的视频时,我发现了一些我无法解释的东西;当他写道:
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次的情况。
2 个解决方案
#1
11
(Updated for Swift >=3)
(更新迅速> = 3)
"Double optionals" can be useful, and the Swift blog entry "Optionals Case Study: valuesForKeys" describes an application.
“双选项”可能有用,Swift博客条目“选项案例研究: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??
aka Optional<Optional<String>>
. It is .none
(or nil
) if the key is not present in the dictionary, and .some(x)
otherwise. In the second case, x
is a String?
aka Optional<String>
and can be .none
(or nil
) or .some(s)
where s
is a String.
字符串类型? ?又名可选 <可选<字符串> >。如果字典中没有键,则为.none(或nil),否则为.some(x)。在第二个例子中,x是一个字符串?可选
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:
如果在切换语句中使用模式匹配来实现相同的功能,可能会很有指导意义:
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?
pattern as a synonym for .some(x)
:
或者,使用x ?模式作为。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.)
(我不知道有什么合理的应用程序可以实现更深层的选项。)
#2
1
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.
我想不出它有什么有用的用途,但它确实存在,因为选项对任何类型的对象都是通用的。嵌套的选项就像放入另一个盒子或数组中的盒子,但又放入另一个数组中。
#1
11
(Updated for Swift >=3)
(更新迅速> = 3)
"Double optionals" can be useful, and the Swift blog entry "Optionals Case Study: valuesForKeys" describes an application.
“双选项”可能有用,Swift博客条目“选项案例研究: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??
aka Optional<Optional<String>>
. It is .none
(or nil
) if the key is not present in the dictionary, and .some(x)
otherwise. In the second case, x
is a String?
aka Optional<String>
and can be .none
(or nil
) or .some(s)
where s
is a String.
字符串类型? ?又名可选 <可选<字符串> >。如果字典中没有键,则为.none(或nil),否则为.some(x)。在第二个例子中,x是一个字符串?可选
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:
如果在切换语句中使用模式匹配来实现相同的功能,可能会很有指导意义:
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?
pattern as a synonym for .some(x)
:
或者,使用x ?模式作为。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.)
(我不知道有什么合理的应用程序可以实现更深层的选项。)
#2
1
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.
我想不出它有什么有用的用途,但它确实存在,因为选项对任何类型的对象都是通用的。嵌套的选项就像放入另一个盒子或数组中的盒子,但又放入另一个数组中。