为什么我需要在Struct-Swift中明确声明一个可选值为nil

时间:2014-06-05 16:27:09

标签: swift

以下是文档的引用:

  

如果您的自定义类型具有逻辑上允许“无值”的存储属性 - 可能是因为在初始化期间无法设置其值,或者因为允许在稍后的某个时间点“无值” - 声明具有可选类型的属性。可选类型的属性会自动初始化,其值为nil,表示该属性在初始化过程中故意“无值”。

如果我用课程这样做,它可以正常工作:

class MyClass {
    var someProperty: String?
}

var myClass = MyClass()
myClass.someProperty // Shows nil

但是,如果我使用结构类型执行此操作,则会在初始化时出现错误:

struct MyStruct {
    var someProperty: String?
}

// ERROR
var myStruct = MyStruct()

错误:

  

缺少参数'someProperty'的参数

我可以通过明确地声明它来解决这个问题:

struct MyStruct {
    var someProperty: String? = nil
}

// Valid
var myStruct = MyStruct()

问题

鉴于文档,我希望任何类型的属性设置为可选项都默认为nil。我有理由在结构上明确声明它吗?

为什么?

没有什么好理由,就像很多人一样,我只是在尝试。

3 个答案:

答案 0 :(得分:12)

Classes和Structs都需要在初始化时设置所有属性值。这可以通过显式默认值或通过在指定的初始化程序中设置值来完成。

但是,Structs的不同之处在于它们具有自动生成的成员初始化程序。

如果您没有明确定义someProperty的值,那么您的结构只有一个初始值设定项:自动生成的成员值。

如果确实提供了默认值,则会得到两个:一个不带参数,另一个带someProperty值作为参数

来自文档:

  

所有结构都有一个自动生成的成员初始化器,   您可以使用它来初始化新结构的成员属性   实例。新实例的属性的初始值可以   按名称传递给成员初始值设定项:

let vga = Resolution(width: 640, height: 480)
  

与结构不同,类实例不会收到默认的成员   初始化。初始化器在后面有更详细的描述   初始化。

答案 1 :(得分:1)

我同意这是相当古怪的(除非我也遗漏了一些东西)。对于选项的结构,可能值得建议(通过Apple bugreport)在这种情况下,默认情况下还会添加默认的无参数初始化器吗?

另一种补救措施是

var myStruct = MyStruct(someProperty:nil)

但是,如果你有很多可选成员,那就会变得很笨拙。

答案 2 :(得分:0)

我认为这是结构和类之间的故意区别,这有点道理。例如,当您有一个结构时,请说一个带有三个浮点数的3d点用于XYZ。为x或y或z设置nil值没有多大意义。另一方面,这是一个非常重要的特征。例如,如果您考虑下载程序类,则会下载文本文件并将其存储在属性中。首次初始化类时,该属性为nil更有意义。由于苹果已经改变结构与课程更紧密相关,我认为这是一个重要的区别。我认为明确将可选项设置为nil是一个错误。


我的理由是:

optional documentation中,所有示例都在类上。