разница между вычисляемым свойством и установкой функции в переменную в Swift

У меня есть два способа установить строку, которую я видел в SO.

Мне интересно, в чем преимущество одного над другим, и может ли кто-нибудь дать мне ссылку на статью или документацию по этому синтаксису.

Я полагаю, что первое называется вычисляемым свойством, и я прочитал раздел «Вычисляемое свойство» на сайте swift.org.

Я думаю, что второй на самом деле просто устанавливает постоянное имя «string2» в замыкание, но я, возможно, не называю это правильным, поэтому я спрашиваю, потому что я не могу найти какие-либо статьи или документацию по этому вопросу. вперед за любую помощь.

var string1: String { return "My first string"}

let string2 = { return "My second string"}()

person jonathan3087    schedule 23.10.2018    source источник
comment
И, конечно, вы можете сделать: let string3 = "My third string".   -  person rmaddy    schedule 24.10.2018


Ответы (2)


Код в вычисляемом свойстве выполняется каждый раз, когда вы ссылаетесь на эту переменную. Код в свойстве, инициализированном замыканием, выполняется только один раз во время инициализации.

person Kon    schedule 23.10.2018
comment
Спасибо @ODYN-Kon, я думаю, что выполнение каждый раз, а не только один раз, действительно помогает моему пониманию в этом случае. Одно дополнение к вопросу. Если бы я сделал замыкание var вместо let, было бы оно все равно выполнено только один раз? - person jonathan3087; 24.10.2018
comment
Кто-нибудь может объяснить, почему он выполняется только один раз? Что это за функциональные скобки за закрытием? В чем отличие от let string3 = {return My Third string } // без круглых скобок функции. Как можно объявить тип String, но назначить замыкание, создающее String? Я знаю, как это использовать, но я действительно не понимаю, ПОЧЕМУ это работает. Спасибо за краткую заметку. - person LukeSideWalker; 24.09.2019
comment
попробуйте let string3 = { return "My third string" } на игровой площадке и изучите тип string3. Это не строка, это замыкание, которое не выполняется до тех пор, пока вы не вызовете его с помощью (). Если поставить круглую скобку сразу после замыкания, то замыкание выполняется немедленно, а результат присваивается string3, который затем будет строкой. - person Kon; 25.09.2019

Именно то, что сказал ODYN. Просто больше контекста о том, где второй тип может быть удобен. В вашем примере это бесполезно, и, возможно, поэтому вы запутались!

var ageOfGrandpa = 87
var ageOfGrandma = 83

class Person {

    var ageAt2018 : Int 

    var ageAt2017 : Int { // computed property
        return ageAt2018 - 1
    }

    var ageAtBirth : Int = 0
    var dumbWay_AgeAtBith : Int = { return 0}() // There is no computation so this is a bad example of instantiation.

    var non_dumbWay_AgeAtBith : Int = 0 // if there is nothing to calculate then just instantiate it with a value!
    var non_dumbWay_AverageAgeOfGrandParents : Int = { // this is where using a block makes sense. There are multiple lines for you to do until you create the value you need
       return (ageOfGrandma + ageOfGrandpa ) / 2
    }()

    init(ageAt2018: Int) {
        self.ageAt2018 = ageAt2018
    }
}

За исключением ageAt2017, все остальные свойства являются хранимыми свойствами. ageAt2017 — это единственное вычисляемое свойство.

person Honey    schedule 24.10.2018
comment
Спасибо, расширенный пример действительно делает его более понятным. Вы правы, что мой пример строки настолько прост, что даже не имеет смысла для вопроса. Спасибо, что смогли увидеть и объяснить, к чему я клоню. Мой реальный случай, очевидно, более сложен: я использую блок для установки и настройки переменной для URLSessionConfiguration. :) - person jonathan3087; 24.10.2018
comment
настройте переменную для URLSessionConfiguration Тогда я просто воспользуюсь вашим вторым подходом, настроив его внутри блока. При необходимости вы можете сделать его ленивым. - person Honey; 24.10.2018