【问题标题】:Why do I need to declare an optional value as nil explicitly in Struct - Swift为什么我需要在 Struct - Swift 中显式声明一个可选值作为 nil
【发布时间】:2014-07-26 18:09:22
【问题描述】:

这是来自文档的引用:

如果您的自定义类型有一个逻辑上允许“无值”的存储属性——可能是因为它的值不能在初始化期间设置,或者因为它允许在稍后的某个时间点有“无值”——声明具有可选类型的属性。可选类型的属性会自动使用 nil 值进行初始化,这表明该属性在初始化期间故意设置为“还没有值”。

如果我用一个类来做这件事,效果很好:

class MyClass {
    var someProperty: String?
}

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

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

struct MyStruct {
    var someProperty: String?
}

// ERROR
var myStruct = MyStruct()

错误:

参数“someProperty”缺少参数

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

struct MyStruct {
    var someProperty: String? = nil
}

// Valid
var myStruct = MyStruct()

问题

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

为什么?

没有充分的理由,就像你们中的许多人一样,我只是在尝试。

【问题讨论】:

    标签: swift


    【解决方案1】:

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

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

    当您没有为someProperty 明确定义值时,您的结构只有一个初始化器:自动生成的成员初始化器。

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

    来自文档:

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

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

    与结构不同,类实例不接收默认成员 初始化器。初始化器在 初始化。

    【讨论】:

    • 啊,是的。这就说得通了。谢谢
    【解决方案2】:

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

    另一种补救措施是

    var myStruct = MyStruct(someProperty:nil)
    

    但是,如果您有很多可选成员,这将变得笨拙。

    【讨论】:

      【解决方案3】:

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


      我的理由:

      optional documentation 中的所有示例都是关于类的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多