Swift可选属性声明之间的区别

时间:2018-05-15 07:53:17

标签: swift optional

我注意到Swift的一些编码示例以不同的方式声明可选属性。但是,我似乎很难将它们分开(或者更确切地说,何时使用它们。)

class MyClass {
   // I believe this can start as nil but should always be set
   // once it is.
   var optionalProperty1: Type!

   // I believe this can be set or nil anytime.
   var optionalProperty2: Type?

   // I think this is the same as
   // var optionalProperty3: Type!
   lazy var optionalProperty3: Type
}

每个人与其他人的区别如何?每个人应该何时使用?

4 个答案:

答案 0 :(得分:1)

var optionalProperty1: Type!

如果您确定自己对此属性有价值,例如timestamp,那么肯定会有所帮助。是的它也可以是nil

var optionalProperty2: Type?

如果您不确定该值(或者此字段不是必填字段),请将其视为optional,例如: - 如果我创建了Personaddressoptionalname不会。

lazy var optionalProperty3: Type

这种语法错误,你不能以这种方式声明lazy属性。您最初必须为其分配一些东西。见下面的例子:

/// First way
lazy var optionalProperty3: String = {
    return "Hello"
}()

/// Second way
lazy var optionalProperty4 = "Hello"

lazy存储属性是一个属性,其初始值在第一次使用之前不会计算。通过在声明之前编写惰性修饰符来指示lazy存储的属性。 lazy变量非常适合需要设置一次,然后永远不会重新设置的内容。

您真正不需要在现代Swift中指定类型。表示如果您要指定0,则它本身就是一个整数,如果您将指定0.0,则会将其作为double,而String则相同,Array

答案 1 :(得分:0)

第三个声明不是可选的。

第三个宣布一个懒惰的财产。延迟属性仅在首次使用时初始化。例如:

class A {
    lazy var a: Int = {
        print("hello")
        return 1 + 1
    }()
}

let a = A()
print(a.a)

如果删除最后一行,则不会打印hello

第一个声明是隐式展开的可选,而第二个声明是普通的可选。

当您访问普通可选项的成员时,需要使用?!打开它:

var myInt: Int? = ...
print(myInt.description) // doesn't compile, must unwrap
print(myInt!.description) // will crash if myInt is nil
print(myInt?.description) // will print "nil" if myInt is nil

另一方面,隐式展开的选项会隐式执行此操作 - 每当您尝试访问某个成员时,它都将隐式使用!为您解包:

var myInt: Int! = ...
print(myInt.description) // equivalent to "myInt!.description"

答案 2 :(得分:0)

来自Apple的Swift文档:

Optionals(?):"您可以在没有值的情况下使用选项。可选项表示两种可能性:要么存在值,要么可以打开可选项以访问该值,或者根本没有值。"

隐式解包的选项(!):"如上所述,选项表示允许常量或变量具有“无值”。可以使用if语句检查可选项以查看是否存在值,并且可以使用可选绑定有条件地解包,以便在可选的值存在时访问它。

有时从程序的结构中可以清楚地看出,在首次设置该值之后,可选项将始终具有值。在这些情况下,每次访问时都不需要检查和解包可选的值,因为可以安全地假设它始终具有值。

这些类型的期权被定义为隐式解包的期权。您通过在要使其成为可选的类型之后放置感叹号(String!)而不是问号(String?)来编写隐式展开的可选项。

如果在首次定义可选项后立即确认可选项的值存在,并且可以假定在此后的每个点都存在,则隐式解包的选项会很有用。 Swift中隐式解包选项的主要用途是在类初始化期间,如Unowned References和Implicitly Unwrapped Optional Properties中所述。"

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html

了解详情

答案 3 :(得分:0)

明确展开的变量

var optionalProperty1: Type!

这意味着该值永远不应为零。它将始终初始化,但最好使用var optionalProperty1: Type

可选

var optionalProperty2: Type?

这是一个可选值,意味着它可以具有值或为零。通常使用打开它所需的值。使用条件展开或保护声明...

if let value = optionalProperty2 {
    print("optionalProperty2 had a value, value is set")
}

guard let value = optionalProperty2 else {
   print("optionalProperty2 was nil value is nil") 
}

或者您可以检查它是否有值并明确展开它(这不是最佳做法)

if optionalProperty2 != nil {
    print("optionalProperty2 is set to \(optionalProperty2!)")
}

懒惰变量

lazy var optionalProperty3: Type惰性变量不同,除非您将其定义为可选,否则它不是可选的。在首次使用该值之前,惰性变量不会初始化为值。因此,如果您不调用/使用该变量,则永远不会设置它。