用于将Swift中的可选项解包的if let语句的第一行转换为

时间:2017-08-10 23:21:29

标签: swift optional

我非常了解选项是什么以及为什么需要它们。但我很好奇在一个if let语句的第一行中发生了什么,它解开了一个可选项。这是一些代码:

var optionalInt : Int?

if let optionalInt = optionalInt {
    print("I have an integer value.")
} else {
    print{"I have a nil value")
}

现在我知道第一行相当于“if optionalInt包含执行此代码块的值”,但我的问题是代码是如何表示的。当编译器读取if let语句的第一行时会发生什么?

3 个答案:

答案 0 :(得分:0)

Optional<T>是一个包含两种情况的枚举:

enum Optional<T> {
    case .none // a.k.a. nil
    case .some(wrapped)
}

它有点像(isPresent: Bool, wrapped: T)类型的元组。当您有条件地展开这样的可选项时,会检查isPresent布尔标志。如果是,则wrapped绑定到您提供的任何变量名称。否则,将调用else个案。

答案 1 :(得分:0)

首先,您需要知道= - if符号中的符号let不是赋值运算符,也不是前导初始值。它只是一个分隔符。

if - let的语义定义为:

  • 如果分隔符的右侧被评估为非零值,则在左侧建立具有展开值和非可选类型的局部变量声明,然后执行true - 阻止。

  • 如果分隔符的右侧是nil,请执行else - 阻止(如果有)。

所以,你的解释“如果optionalInt包含一个执行这段代码的值”并不是完全错误的,只是你不能将这部分let optionalInt = optionalInt作为赋值或正常变量声明也不是简单的非零条件。

答案 2 :(得分:0)

我倾向于考虑两件事:

  • 变量范围,是nil
  • 如果nil
  • 该怎么办

解决这个问题的一个合理方法是将ifguard进行比较。使用您的示例:

var optionalInt:Int?
if let newOptionalInt = optionalInt {
    print("I will do something because I **do have** a value")
} else {
    print{"I will do something **else** because I **do not have** a value")
}

这几乎与:

相同
guard newOptionalInt = optionalInt else {
    print{"I will do something because I **do not have** a value")
}     
print{"I will do something **else** because I **do have** a value")
  • 我做的最大改变是将大多数本地optionalInt转移到newOptionalInt。这是可变范围部分。
  • 如果您有值,guardif的工作方式相同 - 分支处理。
  • 对我说话时,我更喜欢guard,尤其是在func的开头。对于您的意图,它的 更清晰的编码。