Подтвердить что ты не робот

Быстрое ленивое создание

У меня есть что-то, что меня озадачивает, в частности, следующий код вызывает ошибку компилятора "неразрешенный идентификатор self", и я не уверен, почему это происходит, поскольку ленивый означает, что в то время, когда свойство будет использоваться, класс уже создан. Я что-то упускаю?

Большое спасибо заранее.

Вот код

class FirstClass {
    unowned var second: SecondClass

    init(second:SecondClass) {
        self.second = second
        print("First reporting for duty")
    }

    func aMethod() {
        print("First method reporting for duty")
    }
}


class SecondClass {

    lazy var first = FirstClass(second: self)

    func aMethod() {
        first.aMethod()
    }
}
4b9b3361

Ответ 1

По какой-то причине для ленивого свойства требуется явная аннотация типа, если ее начальное значение относится к self. Это упоминается в списке рассылки быстрой эволюции, однако я не могу объяснить, почему это необходимо.

С

lazy var first: FirstClass = FirstClass(second: self)
//            ^^^^^^^^^^^^

ваш код компилируется и работает как ожидалось.

Вот еще один пример, демонстрирующий, что проблема возникает также с struct s, то есть он не связан с подклассом:

func foo(x: Int) -> Int { return x + 1 }

struct MyClass {
    let x = 1

    lazy var y = foo(0)            // No compiler error
    lazy var z1 = foo(self.x)      // error: use of unresolved identifier 'self'
    lazy var z2: Int = foo(self.x) // No compiler error
}

Начальное значение y не зависит от self и не нуждается в тип аннотации. Начальные значения z1/z2 зависят от self, и он компилируется только с явной аннотацией типа.

Обновление: Этот был исправлен в Swift 4/Xcode 9 beta 3, Инициализаторы lazy-свойств теперь могут ссылаться на экземпляры экземпляра без явного self и без явного аннотации типа. (Спасибо @hamish за обновление.)