默认情况下,常量未分配的可选项不会为nil

时间:2016-08-14 12:36:17

标签: swift initialization optional

到目前为止我的理解:如果您定义了一个可选变量而未指定任何值,编译器将自动分配nil

代码段:

A:

var someOptional : Int? //Change to `let` to trigger error 
var aDefaultValue = 42
var theAnswer = someOptional ?? aDefaultValue

上面的代码片段工作正常,但是,当我将变量someOptional更改为常量时,编译器发出错误(请参阅下图)

enter image description here

B:

然后我尝试了类似的代码来解决问题。

var someOptional : Int?
print(someOptional)

尽管如此,它在使用常量类型失败时仍适用于变量。

enter image description here

结论:

如果你定义一个常量可选,你必须明确指定nil。因为它看起来没用(为什么你需要一个带有nil的常量选项),如果编译器自动为你做了这个,它可能会引入错误。

问题:

为什么编译器假定nil声明的选项var而不是let声明的选项?

1 个答案:

答案 0 :(得分:6)

是的,这是正确的

无需手动初始化可选变量。如果您在填充之前阅读它,则确实包含nil

来自Apple docs

  

如果您定义一个可选变量而不提供默认值,则该变量会自动设置为nil [...]

另一方面,编译器会强制您手动初始化一个Optional常量(let),然后才能读取它。

  

与变量不同,一旦设置了常量的值,就无法更改。在编译代码时,尝试这样做会报告错误[...]

为什么?

常量只能写一次。它不需要在它初始化的同一行发生,但它必须在你阅读它之前发生。

E.g。这段代码工作正常

let num: Int?
num = 1
print(num)

但是,如果编译器在nil内放置了一个临时num值,则该常量将被写入两次。这违背了常数的概念。

let num: Int?
print(num) // nil ??? <- this can't work! 
num = 1
print(num) // 1

另一个例子

此代码段正常

func printArea(width: Int?, height:Int?) {
    let area: Int?
    if let width = width, height = height {
        area = width * height
    } else {
        area = nil
    }
    print(area)
}

同样,如果编译器在nil内放置了一个临时area值,那么......

func printArea(width: Int?, height:Int?) {
    let area: Int?
    print(area) // not possible! area is going to change in a moment
     if let width = width, height = height {
        area = width * height
    } else {
        area = nil
    }
    print(area)
}