我注意到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
}
每个人与其他人的区别如何?每个人应该何时使用?
答案 0 :(得分:1)
var optionalProperty1: Type!
如果您确定自己对此属性有价值,例如timestamp
,那么肯定会有所帮助。是的它也可以是nil
。
var optionalProperty2: Type?
如果您不确定该值(或者此字段不是必填字段),请将其视为optional
,例如: - 如果我创建了Person
类address
, optional
和name
不会。
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中所述。"
了解详情答案 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
惰性变量不同,除非您将其定义为可选,否则它不是可选的。在首次使用该值之前,惰性变量不会初始化为值。因此,如果您不调用/使用该变量,则永远不会设置它。