以下是文档的引用:
如果您的自定义类型具有逻辑上允许“无值”的存储属性 - 可能是因为在初始化期间无法设置其值,或者因为允许在稍后的某个时间点“无值” - 声明具有可选类型的属性。可选类型的属性会自动初始化,其值为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。我有理由在结构上明确声明它吗?
为什么?
没有什么好理由,就像很多人一样,我只是在尝试。
答案 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中,所有示例都在类上。