Swift 可选类型的初始化

6

我理解的是

var perhapsInt : Int?

这个自动设置为.None值。下面的代码片段证实了这一点(没有编译器错误)

class MyClass {
    var num1: Int = 0
    var num2: Int?

    init(num1: Int) {
        self.num1 = num1
    }
}

var newClass = MyClass(num1: 5)
newClass.num1 // prints '5'
newClass.num2 // prints 'nil'

我对可选初始化过程的理解正确吗?如果是,为什么当我将num2更改为let时它不起作用。

我原本期望使用let时,可选项的默认值也应该是nil。我错过了什么吗?

class MyClass {
    var num1: Int = 0
    let num2: Int?

    init(num1: Int) {
        self.num1 = num1
        // compiler error : return from initialiser without initialising all stored properties 
    }
}    
...

我的问题是,这两种情况怎么都是正确的呢?难道不应该只有一种情况吗?要么可选值自动设置为.None,要么就不是。

2个回答

7
var num2: Int?的行为是由Optional进行了特殊处理。在Swift中,只有它们具有隐式默认值(即.None)。
请注意,如果您输入var num2: Int(不带?) - 无论使用var还是let,编译器都将抛出相同的错误。
class MyClass {
    var num2: Int
    init() {
        // Return from initializer without initializing all stored properties
    }
}

因为 let 的值不能被覆盖(相对于 var),它们要求你明确地设置它们的初始值:

class MyClass {
    let num2: Int? = nil
}

// or this way

class MyClass {
    let num2: Int?
    init() {
        num2 = nil
    }
}

这将导致一个无用的 nil 常量。
你可以在这里这里了解更多关于存储属性初始化的内容。

好的,这很有道理。谢谢。作为后续问题,为什么在'init'内初始化'let'时它可以工作,但在定义时不初始化就不能工作呢?请看下面的代码块。class MyClass { let num2: Int? init() { self.num2 = nil } }难道这不应该在'let num2: Int?'行周围抛出错误吗? - hdsenevi
不需要多次分配值,let 只要求你分配一次即可。当涉及到初始化时,所有的 let 在初始化完成之前都需要有一个值。因此,你可以通过默认值或者初始化器本身来实现这个目的。 - akashivskyy

1

我认为有很多关于这里的讨论。 来自该主题的一条声明 - 在上面的链接中深入了解

常量的值不必在编译时知道,但你必须准确地为其分配一个值。

有趣的是,如果您像这样设置let值,您的代码将会编译:

let num2: Int? = .None
let num2: Int? = nil

是的,这很有道理,因为在 Swift 中有两种初始化变量(或常量)的方式。1. 默认值(您已经在这里做了)或 2. 使用 init 方法进行初始化。 - hdsenevi

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