每次访问计算属性时都会对其进行评估吗?
Are computed properties evaluated every time they are accessed?
我有两个关于 Swift 中计算属性的问题。
是否在每次访问计算属性时对其进行评估?或者它们存储在某个地方以供将来访问?
这是什么属性,因为我无法google:
let navigationController: UINavigationController = {
var navigator = UINavigationController()
navigator.navigationBar.translucent = false
return navigator
}()
这个是不是每次访问都要评估?
这不是计算 属性。
let navigationController: UINavigationController = {
var navigator = UINavigationController()
navigator.navigationBar.translucent = false
return navigator
}()
它只是一个 存储的 属性 填充了此代码块 return 值的结果。
var navigator = UINavigationController()
navigator.navigationBar.translucent = false
return navigator
当 class 的实例被实例化时执行该块。只有一次。
所以写这个
struct Person {
let name: String = {
let name = "Bob"
return name
}() // <- look at these
}
等同于这个
struct Person {
let name: String
init() {
self.name = "Bob"
}
}
恕我直言,第一种方法更好,因为:
- 它确实允许您在 相同的 "space"
中声明和填充 属性
- 更清晰
- 如果您有多个初始值设定项
,则可以防止代码重复
注意 #1:在 属性
中存储闭包
正如下面评论中 dfri 指出的那样,代码块确实以 ()
结尾。这意味着代码被 评估 并且结果分配给 属性.
另一方面,如果我们删除块末尾的 ()
,我们会得到一些不同的东西,事实上,块是 而不是 评估的。
在这种情况下 Swift 尝试将 stored closure
分配给 属性。这将产生编译错误,因为 属性 具有此类型 UINavigationController
.
使用正确的语法,我们可以在 属性.
中放置一个闭包
struct Person {
let sayHello: ()->() = { print("Hello") }
}
现在我们有一个包含闭包的 sayHello
属性。闭包接收 0 个参数并执行 return Void
.
let bob = Person()
bob.sayHello // this does NOT execute the code inside closure
bob.sayHello() // this does execute the code in the closure and does print the message
注意#2:让我们谈谈计算属性
所以我们明确了这道题的代码是不是一个Computed Property
。
但是,正如 EmilioPelaez 在下面的另一条评论中指出的那样,我们还应该声明 Computed Property
每次 被评估 它被访问。
在下面的示例中,我创建了一个 Computed 属性 age
。如您所见,我每次调用它时,块中的代码也会被执行。
计算示例 属性 (age
)
我有两个关于 Swift 中计算属性的问题。
是否在每次访问计算属性时对其进行评估?或者它们存储在某个地方以供将来访问?
这是什么属性,因为我无法google:
let navigationController: UINavigationController = {
var navigator = UINavigationController()
navigator.navigationBar.translucent = false
return navigator
}()
这个是不是每次访问都要评估?
这不是计算 属性。
let navigationController: UINavigationController = {
var navigator = UINavigationController()
navigator.navigationBar.translucent = false
return navigator
}()
它只是一个 存储的 属性 填充了此代码块 return 值的结果。
var navigator = UINavigationController()
navigator.navigationBar.translucent = false
return navigator
当 class 的实例被实例化时执行该块。只有一次。
所以写这个
struct Person {
let name: String = {
let name = "Bob"
return name
}() // <- look at these
}
等同于这个
struct Person {
let name: String
init() {
self.name = "Bob"
}
}
恕我直言,第一种方法更好,因为:
- 它确实允许您在 相同的 "space" 中声明和填充 属性
- 更清晰
- 如果您有多个初始值设定项 ,则可以防止代码重复
注意 #1:在 属性
中存储闭包正如下面评论中 dfri 指出的那样,代码块确实以 ()
结尾。这意味着代码被 评估 并且结果分配给 属性.
另一方面,如果我们删除块末尾的 ()
,我们会得到一些不同的东西,事实上,块是 而不是 评估的。
在这种情况下 Swift 尝试将 stored closure
分配给 属性。这将产生编译错误,因为 属性 具有此类型 UINavigationController
.
使用正确的语法,我们可以在 属性.
中放置一个闭包struct Person {
let sayHello: ()->() = { print("Hello") }
}
现在我们有一个包含闭包的 sayHello
属性。闭包接收 0 个参数并执行 return Void
.
let bob = Person()
bob.sayHello // this does NOT execute the code inside closure
bob.sayHello() // this does execute the code in the closure and does print the message
注意#2:让我们谈谈计算属性
所以我们明确了这道题的代码是不是一个Computed Property
。
但是,正如 EmilioPelaez 在下面的另一条评论中指出的那样,我们还应该声明 Computed Property
每次 被评估 它被访问。
在下面的示例中,我创建了一个 Computed 属性 age
。如您所见,我每次调用它时,块中的代码也会被执行。
计算示例 属性 (age
)