Странная ошибка «self», захваченная закрытием до инициализации всех членов » - PullRequest
4 голосов
/ 30 апреля 2019

Пожалуйста, посмотрите на следующий код:

class A {
    let a: String
    let b: String

    init(a: String, b: String) {
        self.a = a
        self.b = b
    }
}

class B: A {
    let c: Bool

    private let aExpectedValue = "a"
    private let bExpectedValue = "b"

    override init(a: String, b: String) {
        c = (a == aExpectedValue && b == bExpectedValue)
        super.init(a: a, b: b)
    }
}

Это вызывает ошибку в B.init:

error

Однако, если я изменю его на c = (a == aExpectedValue) или c = (b == bExpectedValue), он будет скомпилирован правильно.

Кто-нибудь знает, почему это так?

Ответы [ 2 ]

12 голосов
/ 30 апреля 2019

Проблема в bExpectedValue.Это свойство экземпляра в B.Это взаимодействует с определением && в Bool:

static func && (lhs: Bool, rhs: @autoclosure () throws -> Bool) rethrows -> Bool

. @autoclosure превращает b == bExpectedValue в замыкание, фиксируя его как self.bExpectedValue.Это не разрешено до завершения инициализации.(Закрытие здесь разрешает короткое замыкание. Замыкание rhs не оценивается, если lhs ложно.)

Это довольно неловко (см. SR-944 , на который MartinR ссылается для небольшого количестваобсуждение этого вопроса).

Если бы bExpectedValue были static, или если бы он был перемещен за пределы определения класса, то это не было бы проблемой.Следующий подход также исправит это:

override init(a: String, b: String) {
    let goodA = a == aExpectedValue
    let goodB = b == bExpectedValue
    c = goodA && goodB
    super.init(a: a, b: b)
}
0 голосов
/ 30 апреля 2019

Вам нужно создать новый инициализатор с другими переменными или вызвать super.init (a :, b :) перед любым выражением с этими свойствами.

Позвоните по этому номеру:

override init(a: String, b: String) {
    super.init(a: a, b: b)
    c = (a == aExpectedValue && b == bExpectedValue)        
}

или измените его на:

init(newA: String, newB: String) {
    c = (newA == aExpectedValue && newB == bExpectedValue)        
    super.init(a: newA, b: newB)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...