从苹果公司发布的Swift书中,我们可以通过推出来制作可选值吗?到像
这样的变量var optionalString: String? = "Hello"
optionalString == nil
并且还写道“你可以使用if和let一起处理可能缺失的值。”
var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {
greeting = "Hello, \(name)"
}
上面写的代码用于检查可选值是否为nil,如果optionalName为nil,则不会进入。
但是可以在不使用let之类的情况下完成相同的操作
if optionalName {
greeting = "Hello, \(optionalName!)"
}
为什么在书中建议使用let?
答案 0 :(得分:14)
您的第二个代码段在功能上等同于本书中的代码段。但是,本书建议使用let
来避免多次展开可选值。
由于您检查optionalName
是否为空,因此可以安全地假设您计划在条件块中使用它。当你这样做时,Swift需要再次从optionalName
打开可选值,因为变量仍然是可选的。
当您在optionalName
声明中分配name
到let
时,您获得的name
常量不可选。这样可以省去if
语句中的解包。
答案 1 :(得分:2)
由于您使用println显示optionalName,因此println非常智能,可以处理可选值并根据需要解包它们。如果您使用假设相似的代码:
if optionalName {
greeting = "Hello, " + optionalName
}
你会得到一个错误,因为你不能连接一个字符串和一个字符串?你有三种方法
首先,您可以在执行检查后使用条件展开,但这样做效率很低,因为如果您多次引用optionalName,则必须每次都将其解包。
if optionalName {
greeting = "Hello, " + optionalName?
}
您可以通过使用强制解包来改进它,因为您已经完成了测试,并且知道optionalName永远不会是nil。如果您多次引用optionalName,那么这仍然是低效的,因为每次必须完成展开。
if optionalName {
greeting = "Hello, " + optionalName!
}
最后,您可以使用if let语法同时测试和解包所有内容。名称是安全的,因为它将是String类型,而不是String?
if let name = optionalName {
greeting = "Hello, " + name
}
答案 2 :(得分:-1)
我来自红宝石世界,其中“Hello,(optionalName)”将返回“Hello”,即如果optionalName为nil则插入空字符串。目前如果optionalName为nil,则Swift打印“Hello,nil”,如果它不是nil,则打印“Hello,Optional(”John“)”。当使用“Hello,(optionalName!)”时,它会打印“Hello,John”,如果optionalName为nil,则会导致运行时错误。对于rubyist磕磕绊绊地想知道如何实现ruby行为:
let EMPTY_STRING = ""
var greeting = "Hello, \(optionalName ? optionalName! : EMPTY_STRING)"