что делают скобки после ленивого определения var?

Я анализирую анализ некоторого стороннего кода, и есть «ленивый» оператор var, который выглядит так, и я хотел бы понять, что делают круглые скобки после фигурных скобок «вычисляемого свойства»:

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

«return .standardUserDefaults()» возвращает объект экземпляра NSUserDefaults, так зачем добавлять () после правой фигурной скобки?

Благодарность


person malena    schedule 06.02.2016    source источник


Ответы (2)


Это означает, что это блок, который выполняется при первом доступе к значениям по умолчанию. Без () это означает, что по умолчанию используется блочный тип переменной типа () -> NSUserDefaults. Когда вы добавляете (), это означает, что это просто NSUserDefaults, который возвращается блоком, выполненным во время доступа.

person Pradeep K    schedule 06.02.2016
comment
Спасибо, да, это имеет смысл. Что меня смущает, так это то, что фигурные скобки делают его похожим на вычисляемое свойство без get. Как компилятор узнает, что это не вычисляемое свойство, а блок/замыкание? - person malena; 06.02.2016
comment
() в конце блока является индикатором того, что это вызов блока, а не сам блок. - person Pradeep K; 06.02.2016
comment
Я до сих пор не совсем понимаю - это замыкание? есть подробное объяснение по этому поводу? Это объяснение (которое выглядит нормально) ДОЛЖНО быть в быстрой документации Apple ... где я могу его найти? И мне также интересно, где это можно найти в хорошей книге по Свифту? Я искал книгу Apple и другие книги, но ничего не нашел - person mlev; 26.01.2017

Я придумал два примера. Первый пример — ваш типичный computed property. Он запускается каждый раз, когда вызывается переменная.

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


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

Второй пример — self-executing closure. Как видите, он запускает print(num) только при первом вызове.

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


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

Чтобы еще больше проиллюстрировать, я вернул число и посмотрел, изменится ли оно в SEC. Это не так. Это означает, что блок запускается только при первом вызове и после этого присваивает себе возвращаемое значение. Во всех смыслах и целях после первого вызова MyNum теперь равен 0 и больше не является блоком.

var num = 0
var myNum: Int = {
    print(myNum)
    return myNum
}()


print(myNum)
// 0
// 0
num += 1
print(myNum)
// 0
person Xavier Chia    schedule 05.07.2021