懒惰变量定义后的括号有什么作用?

7

我正在分析一些第三方代码,发现有一个“lazy”变量声明看起来像这样,并且我想了解在“计算属性”花括号后面的括号是做什么用的:

lazy var defaults:NSUserDefaults = {
    return .standardUserDefaults()
}()

"return .standardUserDefaults()" 返回NSUserDefaults实例对象,为什么在右大括号后面加上()?
谢谢
2个回答

14

这意味着第一次访问defaults时执行的是一个块。没有()表示defaults是() -> NSUserDefaults类型的块变量。添加()表示访问时执行的块返回的只是NSUserDefaults


谢谢,没错,确实有道理。让我困惑的是花括号让它看起来像一个没有get的“计算属性”。编译器如何知道它不是计算属性而是块/闭包? - malena
2
块末尾的括号是指示它是一个块调用而不是块本身的指示器。 - Pradeep K
4
我仍然不完全理解它——它是一个闭包吗?是否有详细的解释?这个(看起来还可以)解释必须在苹果的Swift文档中……我在哪里能找到它?我也想知道在一本好的Swift书中它可以在哪里找到?我搜索了苹果图书和其他书籍,但没有找到。 - mlev

6

我想举两个例子。第一个例子是您典型的计算属性。每次调用变量时都会运行。

var num = 0
var myName: String {
    print(num)
    return "xxx"
}


print(myName)
// 0
// xxx
num += 1
print(myName)
// 1
// xxx

第二个例子是一个“自执行闭包”。如您所见,它只在第一次调用时运行print(num)。
var num = 0
var myName: String = {
    print(num)
    return "xxx"
}()


print(myName)
// 0
// xxx
num += 1
print(myName)
// xxx

为了进一步说明,我已经返回了num并查看它是否在一个SEC中发生了变化。它没有变化。这意味着该块仅在第一次调用时运行,并在此后分配自身的返回值。从所有方面来看,在第一次调用后,MyNum现在为0,不再是块。
var num = 0
var myNum: Int = {
    print(num)
    return num
}()


print(myNum)
// 0
// 0
num += 1
print(myNum)
// 0

感谢您清晰的解释!您知道这是否是线程安全的吗? - CyberMew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接