请看下面的代码:

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中的错误:

swift - 在初始化所有成员之前,闭包捕获了奇怪的 “' self”错误-LMLPHP

但是,如果我将其更改为c = (a == aExpectedValue)c = (b == bExpectedValue),则可以正确编译。

有人知道为什么吗?

最佳答案

问题出在bExpectedValue中。那是B上的一个实例属性。这与Bool上&&的定义相互作用:

static func && (lhs: Bool, rhs: @autoclosure () throws -> Bool) rethrows -> Bool
@autoclosure使b == bExpectedValue成为一个闭包,将其捕获为self.bExpectedValue。初始化完成之前是不允许的。 (此处的闭合是为了允许短路。如果lhs为false,则不会评估rhs闭合。)

这很尴尬(请参阅MartinR引用的SR-944进行一些讨论)。

如果bExpectedValuestatic,或者如果它已移到类定义之外,那么这将不是问题。以下方法也可以解决此问题:
override init(a: String, b: String) {
    let goodA = a == aExpectedValue
    let goodB = b == bExpectedValue
    c = goodA && goodB
    super.init(a: a, b: b)
}

关于swift - 在初始化所有成员之前,闭包捕获了奇怪的 “' self”错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55922486/

10-10 11:51