Lazy Необязательное свойство Always nil?

Есть ли причина, по которой следующий код всегда выводит nil?

class Foo
{
    @lazy var bar: Int? = 5
}

println(Foo().bar)

Я бы подумал, что при доступе к свойству bar он будет инициализирован 5.

Ответ 1

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

class Foo {
    lazy var bar = Int(5)
}

print(Foo().bar)

Ответ 2

Потому что bar обернут необязательным. Вам сначала нужно развернуть его, чтобы использовать его. Либо с! Оператор или оператор if let.

Edit:

Кажется, что при использовании @lazy с родными типами существует ошибка. См. этот вопрос. Помните, что Swift еще не достиг 1.0, поэтому у компилятора могут быть некоторые ошибки, и язык может измениться.

Ответ 3

Как и в Xcode6beta-3, эта ошибка "исправлена" и введена новая "функция"

$ swift
Welcome to Swift!  Type :help for assistance.
  1> class Foo { @lazy var bar: Int? = 5 }
  2> var f = Foo()
f: Foo = {
  bar.storage = nil
}
  3> f.bar
$R0: Int? = 5 // working good
  4> f.bar = nil // use new "feature" to reset bar
  5> f
$R2: Foo = {
  bar.storage = nil
}
  6> f.bar
$R3: Int? = 5 // not sure is this what I want
  7>

f.bar теперь дает вам 5. Он также ввел "функцию", которая позволяет вам не инициализировать переменную @lazy, назначив ей nil. Затем в следующий раз, когда вы вызываете f.bar, вы снова получите 5.

Ответ 4

FYI: в Xcode 6.1.1 следующий код

class Foo
{
    lazy var bar: Int? = 5
}

var foo = Foo ()
println(foo.bar)
foo.bar = 6
println(foo.bar)
foo.bar = nil
println(foo.bar)
foo.bar = 7
println(foo.bar)

выводит вывод

Optional(5)
Optional(6)
nil
Optional(7)

как и следовало ожидать.

Ответ 5

Я не думаю, что вам нужно иметь ленивое необязательное свойство с начальным значением (на мой взгляд). Я бы рекомендовал использовать рассчитанное свойство.

Если вы хотите, чтобы это свойство только для чтения:

var bar: Int {
    return 5
}

еще

var bar: Int? {
    get {
        return 5
    }
    set {
        bar = newValue!
    }
}