带闭包的惰性变量
lazy variable with closure
在这个article中,它说(参考下面的代码):"You must use lazy to prevent the closure for being created more than once."
private lazy var variable:SomeClass = {
let fVariable = SomeClass()
fVariable.value = 10
return fVariable
}()
为什么 lazy 会阻止多次创建闭包?为什么缺少惰性会导致它多次求值?
你的直觉是对的,那篇文章是错误的。我猜作者是 conflating/confusing computed 属性 语法和立即执行关闭技巧。 lazy
关键字与闭包执行了多少次无关。 lazy
只是导致 属性 在第一次访问之前保持未初始化状态,此时等号右侧的表达式被计算。
为了简化,这个:
var myVar: MyType {
return MyType()
}
与此有很大不同:
var myVar: MyType = MyType()
它在存储方面类似,但初始化语义与此不同:
lazy var myVar: MyType = MyType()
在第一个示例中,myVar
是计算得到的 属性,每次访问 myVar
时都会执行大括号内的代码。换句话说,每次你访问 myVar
你都会得到一个新创建的对象。
在第二个例子中,myVar
是一个存储的 属性 并且等号后的表达式在 class 或包含 [=46 的结构的初始化期间计算一次=].
在第三个例子中,myVar
仍然是一个存储的属性但是等号后面的表达式的计算(无论是初始化表达式、函数调用还是闭包调用)被延迟,直到它被访问。
作为旁注,这行代码:
lazy var myVar: MyType = { ... }()
相当于:
func doStuffAndReturnMyType() { ... }
lazy var myVar: MyType = doStuffAndReturnMyType()
第一个示例中的 shorthand 并不是专门为 - 它工作只是因为 Swift 的类型系统(很棒并且)将闭包视为未命名(匿名)函数。
你引用的教程代码是这样的:
private lazy var variable:SomeClass = {
let fVariable = SomeClass()
fVariable.value = 10
return fVariable
}()
对比一下:
private var variable:SomeClass {
let fVariable = SomeClass()
fVariable.value = 10
return fVariable
}
第一个将 variable
初始化为新创建的 SomeClass 实例,最多一次(甚至可能没有那么多次)。第二个是只读计算变量,每次读取其值时都会创建一个新的 SomeClass 实例。
在这个article中,它说(参考下面的代码):"You must use lazy to prevent the closure for being created more than once."
private lazy var variable:SomeClass = {
let fVariable = SomeClass()
fVariable.value = 10
return fVariable
}()
为什么 lazy 会阻止多次创建闭包?为什么缺少惰性会导致它多次求值?
你的直觉是对的,那篇文章是错误的。我猜作者是 conflating/confusing computed 属性 语法和立即执行关闭技巧。 lazy
关键字与闭包执行了多少次无关。 lazy
只是导致 属性 在第一次访问之前保持未初始化状态,此时等号右侧的表达式被计算。
为了简化,这个:
var myVar: MyType {
return MyType()
}
与此有很大不同:
var myVar: MyType = MyType()
它在存储方面类似,但初始化语义与此不同:
lazy var myVar: MyType = MyType()
在第一个示例中,myVar
是计算得到的 属性,每次访问 myVar
时都会执行大括号内的代码。换句话说,每次你访问 myVar
你都会得到一个新创建的对象。
在第二个例子中,myVar
是一个存储的 属性 并且等号后的表达式在 class 或包含 [=46 的结构的初始化期间计算一次=].
在第三个例子中,myVar
仍然是一个存储的属性但是等号后面的表达式的计算(无论是初始化表达式、函数调用还是闭包调用)被延迟,直到它被访问。
作为旁注,这行代码:
lazy var myVar: MyType = { ... }()
相当于:
func doStuffAndReturnMyType() { ... }
lazy var myVar: MyType = doStuffAndReturnMyType()
第一个示例中的 shorthand 并不是专门为 - 它工作只是因为 Swift 的类型系统(很棒并且)将闭包视为未命名(匿名)函数。
你引用的教程代码是这样的:
private lazy var variable:SomeClass = {
let fVariable = SomeClass()
fVariable.value = 10
return fVariable
}()
对比一下:
private var variable:SomeClass {
let fVariable = SomeClass()
fVariable.value = 10
return fVariable
}
第一个将 variable
初始化为新创建的 SomeClass 实例,最多一次(甚至可能没有那么多次)。第二个是只读计算变量,每次读取其值时都会创建一个新的 SomeClass 实例。