Swift 是否每次访问计算属性时都对其进行评估?
关于Swift中的计算属性,我有两个问题 是否每次访问计算属性时都对其进行评估?或者它们被存储在某个地方以备将来使用 这是什么样的财产,因为我无法用谷歌搜索出来:Swift 是否每次访问计算属性时都对其进行评估?,swift,properties,computed-properties,Swift,Properties,Computed Properties,关于Swift中的计算属性,我有两个问题 是否每次访问计算属性时都对其进行评估?或者它们被存储在某个地方以备将来使用 这是什么样的财产,因为我无法用谷歌搜索出来: let navigationController: UINavigationController = { var navigator = UINavigationController() navigator.navigationBar.translucent = false return navigator }()
let navigationController: UINavigationController = {
var navigator = UINavigationController()
navigator.navigationBar.translucent = false
return navigator
}()
是否每次访问时都会对其进行评估?这不是计算属性。
它只是一个存储属性,由该代码块返回的值的结果填充
var navigator = UINavigationController()
navigator.navigationBar.translucent = false
return navigator
在实例化类的实例时执行该块。只有一次
那么写这个
struct Person {
let name: String = {
let name = "Bob"
return name
}() // <- look at these
}
IMHO第一种方法更好,因为:
- 它确实允许您在相同的“空间”中声明和填充属性
- 它更清晰
- 如果有多个初始值设定项,则可防止代码重复
()
结尾。这意味着对代码进行了评估,并将结果分配给属性
struct Person {
let sayHello: ()->() = { print("Hello") }
}
另一方面,如果我们删除块末尾的()
,我们会得到不同的结果,事实上块是而不是计算的。
在这种情况下,Swift会尝试将存储的闭包
分配给属性。这将产生编译错误,因为属性具有此类型UINavigationController
使用正确的语法,我们可以在属性中放置闭包
struct Person {
let sayHello: ()->() = { print("Hello") }
}
现在我们有了一个sayHello
属性,它包含一个闭包。闭包接收0个参数并返回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:让我们谈谈计算属性
因此,我们明确指出,这个问题中的代码是而不是计算属性
。
然而,正如EmilioPelaez在下面的另一条评论中所指出的,我们还应该声明,计算属性
在每次访问时都会进行评估
在下面的示例中,我创建了一个计算属性age
。正如您每次调用它时所看到的,块中的代码也会被执行
计算属性的示例(age
)
是的,代码只执行一次。您可以在该代码块中添加一个
打印(“测试”)
,并对其进行验证。可能值得一提的是,最后一个大括号后的()
是这里的关键(通过运行一次匿名闭包块初始化navigationController
属性)。例如,删除此最后一行()
,并“略微”将顶行修改为let navigationController:()->(UINavigationController)={…
将生成一个存储的闭包,该闭包返回UINavigationController
实例的.translucent=false
。此闭包反过来可以用来代替上面的匿名块,即使用闭包名而不是{…}
块:让myNavigationController=navigationController()
@dfri:我完全同意。我会在回答中加入这一考虑因素。谢谢。您还应该在第一个问题中添加答案,计算机属性在每次访问时都是计算机的。@appzYourLife最后一条提示:我删除了()
但也必须将UINavigationController
类型替换为闭包类型…:()->(UINavigationController)=…
而不是先前的…:UINavigationController=…
。如果我们只删除()
在这里,我们将得到一个编译时错误。但是我们可以不使用显式类型,而是让Swift来推断这些类型,因此例如,对于让foo={()->Int in 1}()
来说,最终的()
是将1
分配给foo
(包括最终的()
,=>foo
是Int
)或将()->Int
闭包分配给foo
(省略()
)。
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