为什么在Swift中会同时使用if和let,而不仅仅检查原变量是否为nil?

5
在苹果公司的《Swift编程语言》一书中,提到了在访问可选变量时同时使用iflet。该书给出了以下示例代码:
var optionalString: String? = "Hello"
optionalString == nil

var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {
    greeting = "Hello, \(name)"
}

使用if let name = optionalName有什么优势,而不是使用if optionalName != nil(并始终将其称为optionalName)?有什么区别,还是只是惯例?
2个回答

12

因为它也解包可选值,所以这段代码:

if let name = optionalName {
    greeting = "Hello, \(name)"
}

等同于:

if optionalName != nil {
    let name:String = optionalName!
    greeting = "Hello, \(name)"
}

这种语法糖在Swift中被称为可选绑定

可选类型

在Swift中,TT?不是相同的类型,但是可选类型T?的基础值可以使用后缀运算符!轻松实现,例如:

let name:String = optionalName!

现在可以在期望String的地方使用它, 例如:

func greet(name:String) -> String {
    return "Hello, \(name)"
}

greet(name)

尽管这样做是安全的,Swift确实允许您隐式转换为可选类型:
let name = "World"
let optionalName: String? = name

func greet(optionalName:String?) -> String? {
    if optionalName != nil {
        return "Hello, \(optionalName)"
    }
    return nil
}

//Can call with either String or String?
greet(optionalName)
greet(name)

2
如果你想在期望未包装值的地方使用它,即 TT? 不是相同的类型,则需要这样做。 - mythz
那么 greeting = "Hello, \(optionalName)" 在第二个例子中就不起作用了吗? - nhgrif
2
@mythz 你应该在你的回答里加上那个注释。TT? 的概念非常重要。 - Rui Peres
你确定它解包了可选项吗?我现在无法测试,但上次尝试时,我相当确定名称仍然是一个可选项。 - Connor
"Hello, (optionalName)" 也可以正常工作,因为(如果我理解正确的话)字符串插值会自动展开值。但是 "hello " + optionalName 就不行。 - Martin R
显示剩余2条评论

0

在这种情况下实际上并不需要。你可以在if语句中直接使用optionalName。但是,如果optionalName是一个计算属性,那么它必须在条件语句中进行计算,然后再在代码块中计算一次。将其赋值给name只是为了确保它只被计算一次。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接