什么时候使用 ?、!、None 或 Lazy?
When to use ?, !, None, or Lazy?
我刚开始学习 Swift 并且最近发现了
"Normal" 变量(因为没有更好的名字):
例如:var test1: String
"Optional" 变量
例如:var test2: String?
"Implicitly Unwrapped Optionals"
例如:var test3: String!
惰性变量
例如:lazy var test4: String
我的理解是这样的:
使用"Optional"变量(?)当变量可能会或可能不会在未来从初始化开始的时间点被初始化
使用"Implicitly Unwrapped Optionals"(!)时保证变量被初始化
Optionals 可以通过 "Forced Unwrapping"
转换为 Implicitly Unwrapped Optionals
例如:let possibleString: String? = "Hello"
println(possibleString!)
使用"Lazy variables"当在初始化之前不需要设置某些东西时(似乎这些可以与(?)一起使用或(!))
因此,我的问题是:
什么时候使用选项 1 - 一个不带 的变量?没有 !
什么时候用"lazy"
我读到 "lazy" 通常用于 singletons - 为什么?
我在 Java 和 C++ 术语方面经验最丰富,如果这对我的回答背景有帮助的话。
编辑:这是我发现的所有内容(主要问题是 "Normal" 与 "Implicitly Unwrapped Optionals":
- "Normal" 变量 必须初始化:(a) 在同一行,(b) 在使用前在相同的范围内(使用意味着对对象的一些操作), (c) init结束时iff变量是一个字段。 注意:init 的范围是 class 范围内的所有内容,而不是 class.
内的函数范围内的所有内容
- 打印一个 隐式展开可选 将打印 "nil",但使用变量的函数将抛出一个 运行time 异常。同时,使用(包括 print)Normal 变量根本不允许程序编译
- 使用目的!在 "" (Nothing) 之上是 (a) 更宽松,因为程序将编译(并且 运行 正确地考虑到变量实际上已初始化)和 (b) 让您不要在一开始就初始化所有内容。 注意:如果任何字段是普通变量,则未声明的字段是编译时错误。
让我们看看苹果的例子
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 1
}
Residence 实例有一个名为 numberOfRooms 的 Int 属性,默认值为 1。Person 实例有一个可选的 residence 属性,类型为 Residence?。
如果你创建一个新的 Person 实例,它的驻留 属性 由于是可选的,所以默认初始化为 nil。
1. 如果您需要 默认值 使 属性 为 nil - 使用可选的。使用没有变量?和 ! - 喜欢 'numberOfRooms' -
您可以在初始化程序中设置已存储 属性 的初始值,如上所示。或者,指定一个默认的 属性 值作为 属性 声明的一部分。您可以通过在定义 属性 时为其分配初始值来指定默认 属性 值。
注意
If a property always takes the same initial value, provide a default
value rather than setting a value within an initializer. The end
result is the same, but the default value ties the property’s
initialization more closely to its declaration. It makes for shorter,
clearer initializers and enables you to infer the type of the property
from its default value. The default value also makes it easier for you
to take advantage of default initializers and initializer inheritance.
2.!用于 访问包装在变量中的值,当它不是 nil 时,否则抛出异常。所以,你可以使用!为了给你们的用户打分 class - 'this value will not be nil at the time you unwrap it'
3. 惰性变量被使用当你想稍后初始化它时,不是在创建整个对象时而是恰好在您向 getter 索要数据的时间。这在 属性 存储数组时很有用,例如:
lazy var players: [String] = {
var temporaryPlayers = [String]()
temporaryPlayers.append("John Doe")
return temporaryPlayers
}()
什么时候应该使用惰性初始化?
何时使用惰性初始化的一个例子是 属性 的初始值直到对象初始化后才知道。
不完全是这样。
所有变量必须在首次使用前初始化,所有 class/struct 存储的属性必须在各自的初始化程序中赋值。 Optionals 不是允许在某些时候未初始化,而是允许不包含任何值,由 nil
表示,这仍然是此类变量的完美初始化声明。因此,如果在初始化时无法知道某些事情,那么您可能会在其中使用某种可选的(例如,委托视图)。
隐式解包选项是一种 shorthand 用于变量可能为空的情况,但我们绝对确定当我们真正使用它时它会保存一个实际值(典型示例是属性 在持有对视图的引用的视图控制器中)。
强制解包不会将可选转换为隐式解包的可选,相反,它会为您提供一个值,如果它存在(即如果可选不存在 nil
),如果不存在则抛出异常。
惰性属性用于您希望将它们的初始化推迟到稍后阶段的情况,此时 属性 实际上是第一次使用。通常的情况是,如果您需要访问昂贵的资源来执行此操作(从磁盘加载大文件,通过网络下载等),尤其是在可能不会使用 属性 的情况下全部(如果我们可能不会使用它,为什么要从磁盘加载它?)。
简短说明:
一个非可选变量总是有一个值并且永远不会为零。
必须在 init 方法或声明行中初始化变量。
var a : String
var b = "bar"
init {
a = "foo"
}
隐式展开的可选变量必须不在init方法中初始化
或在声明行中,但保证在使用时始终具有值
var a : String!
func viewDidLoad() {
a = "Hello"
a += " world!"
}
一个可选变量可能有一个值并且在声明时为零
var a : String? // = nil
一个惰性变量在它第一次使用的那一刻稍后被初始化
class foo {
lazy var bar : String = {
return "Hello"
}()
}
我刚开始学习 Swift 并且最近发现了
"Normal" 变量(因为没有更好的名字):
例如:
var test1: String
"Optional" 变量
例如:
var test2: String?
"Implicitly Unwrapped Optionals"
例如:
var test3: String!
惰性变量
例如:
lazy var test4: String
我的理解是这样的:
使用"Optional"变量(?)当变量可能会或可能不会在未来从初始化开始的时间点被初始化
使用"Implicitly Unwrapped Optionals"(!)时保证变量被初始化
Optionals 可以通过 "Forced Unwrapping"
转换为 Implicitly Unwrapped Optionals例如:
let possibleString: String? = "Hello" println(possibleString!)
使用"Lazy variables"当在初始化之前不需要设置某些东西时(似乎这些可以与(?)一起使用或(!))
因此,我的问题是:
什么时候使用选项 1 - 一个不带 的变量?没有 !
什么时候用"lazy"
我读到 "lazy" 通常用于 singletons - 为什么?
我在 Java 和 C++ 术语方面经验最丰富,如果这对我的回答背景有帮助的话。
编辑:这是我发现的所有内容(主要问题是 "Normal" 与 "Implicitly Unwrapped Optionals":
- "Normal" 变量 必须初始化:(a) 在同一行,(b) 在使用前在相同的范围内(使用意味着对对象的一些操作), (c) init结束时iff变量是一个字段。 注意:init 的范围是 class 范围内的所有内容,而不是 class. 内的函数范围内的所有内容
- 打印一个 隐式展开可选 将打印 "nil",但使用变量的函数将抛出一个 运行time 异常。同时,使用(包括 print)Normal 变量根本不允许程序编译
- 使用目的!在 "" (Nothing) 之上是 (a) 更宽松,因为程序将编译(并且 运行 正确地考虑到变量实际上已初始化)和 (b) 让您不要在一开始就初始化所有内容。 注意:如果任何字段是普通变量,则未声明的字段是编译时错误。
让我们看看苹果的例子
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 1
}
Residence 实例有一个名为 numberOfRooms 的 Int 属性,默认值为 1。Person 实例有一个可选的 residence 属性,类型为 Residence?。
如果你创建一个新的 Person 实例,它的驻留 属性 由于是可选的,所以默认初始化为 nil。
1. 如果您需要 默认值 使 属性 为 nil - 使用可选的。使用没有变量?和 ! - 喜欢 'numberOfRooms' -
您可以在初始化程序中设置已存储 属性 的初始值,如上所示。或者,指定一个默认的 属性 值作为 属性 声明的一部分。您可以通过在定义 属性 时为其分配初始值来指定默认 属性 值。
注意
If a property always takes the same initial value, provide a default value rather than setting a value within an initializer. The end result is the same, but the default value ties the property’s initialization more closely to its declaration. It makes for shorter, clearer initializers and enables you to infer the type of the property from its default value. The default value also makes it easier for you to take advantage of default initializers and initializer inheritance.
2.!用于 访问包装在变量中的值,当它不是 nil 时,否则抛出异常。所以,你可以使用!为了给你们的用户打分 class - 'this value will not be nil at the time you unwrap it'
3. 惰性变量被使用当你想稍后初始化它时,不是在创建整个对象时而是恰好在您向 getter 索要数据的时间。这在 属性 存储数组时很有用,例如:
lazy var players: [String] = {
var temporaryPlayers = [String]()
temporaryPlayers.append("John Doe")
return temporaryPlayers
}()
什么时候应该使用惰性初始化?
何时使用惰性初始化的一个例子是 属性 的初始值直到对象初始化后才知道。
不完全是这样。
所有变量必须在首次使用前初始化,所有 class/struct 存储的属性必须在各自的初始化程序中赋值。 Optionals 不是允许在某些时候未初始化,而是允许不包含任何值,由 nil
表示,这仍然是此类变量的完美初始化声明。因此,如果在初始化时无法知道某些事情,那么您可能会在其中使用某种可选的(例如,委托视图)。
隐式解包选项是一种 shorthand 用于变量可能为空的情况,但我们绝对确定当我们真正使用它时它会保存一个实际值(典型示例是属性 在持有对视图的引用的视图控制器中)。
强制解包不会将可选转换为隐式解包的可选,相反,它会为您提供一个值,如果它存在(即如果可选不存在 nil
),如果不存在则抛出异常。
惰性属性用于您希望将它们的初始化推迟到稍后阶段的情况,此时 属性 实际上是第一次使用。通常的情况是,如果您需要访问昂贵的资源来执行此操作(从磁盘加载大文件,通过网络下载等),尤其是在可能不会使用 属性 的情况下全部(如果我们可能不会使用它,为什么要从磁盘加载它?)。
简短说明:
一个非可选变量总是有一个值并且永远不会为零。 必须在 init 方法或声明行中初始化变量。
var a : String
var b = "bar"
init {
a = "foo"
}
隐式展开的可选变量必须不在init方法中初始化 或在声明行中,但保证在使用时始终具有值
var a : String!
func viewDidLoad() {
a = "Hello"
a += " world!"
}
一个可选变量可能有一个值并且在声明时为零
var a : String? // = nil
一个惰性变量在它第一次使用的那一刻稍后被初始化
class foo {
lazy var bar : String = {
return "Hello"
}()
}