Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 是否每次访问计算属性时都对其进行评估?_Swift_Properties_Computed Properties - Fatal编程技术网

Swift 是否每次访问计算属性时都对其进行评估?

Swift 是否每次访问计算属性时都对其进行评估?,swift,properties,computed-properties,Swift,Properties,Computed Properties,关于Swift中的计算属性,我有两个问题 是否每次访问计算属性时都对其进行评估?或者它们被存储在某个地方以备将来使用 这是什么样的财产,因为我无法用谷歌搜索出来: let navigationController: UINavigationController = { var navigator = UINavigationController() navigator.navigationBar.translucent = false return navigator }()

关于Swift中的计算属性,我有两个问题

是否每次访问计算属性时都对其进行评估?或者它们被存储在某个地方以备将来使用

这是什么样的财产,因为我无法用谷歌搜索出来:

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第一种方法更好,因为:

  • 它确实允许您在相同的“空间”中声明和填充属性
  • 它更清晰
  • 如果有多个初始值设定项,则可防止代码重复
注#1:在属性内存储闭包 正如dfri在下面的注释中所指出的,代码块以
()
结尾。这意味着对代码进行了评估,并将结果分配给属性

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