在下面的类(class)中
class Foo {
let _defaultValue = "N/A"
let value: String
init (dict: NSDictionary) {
self.value = dict["bar"] as? String! ?? _defaultValue
}
}
编译器失败并显示消息
在初始化之前由闭包捕获的常量“self.value”
据我所知,没有运算符读取`self.value。该消息似乎有些令人困惑。
我无意中想到了一个解决方法。我应该说这让我更加困惑:
class Foo {
let value: String
init (dict: NSDictionary) {
let _defaultValue = "N/A"
self.value = dict["bar"] as? String! ?? _defaultValue
}
}
声明 _defaultValue
并在构造函数中初始化它可以使代码编译。
如果有人能够解释为什么在第一种情况下会发生错误以及编译器在第二种情况下更高兴什么?
最佳答案
出现该错误消息的原因是 nil-coalescing 运算符 定义为
public func ??<T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T
并对第二个参数执行“自动关闭”(为了得到 短路行为)。所以
self.value = dict["bar"] as? String ?? _defaultValue
被编译器转换为
self.value = dict["bar"] as? String ?? { self._defaultValue }()
这里编译器会提示,因为 self
之前被捕获
正在完全初始化。 (错误信息略有不同
Swift 2 和 Swift 3 之间)。
可能的解决方法。您可以先将该属性分配给局部变量:
init(dict: NSDictionary){
let defValue = _defaultValue
self.value = dict["bar"] as? String! ?? defValue
}
或者您可以将其设为类的静态属性:
class Foo {
static let _defaultValue = "N/A"
let value: String
init(dict: NSDictionary) {
self.value = dict["bar"] as? String ?? Foo._defaultValue
}
}
或者用 if 语句替换 ??
:
class Foo {
let _defaultValue = "N/A"
let value: String
init (dict: NSDictionary) {
if let value = dict["bar"] as? String {
self.value = value
} else {
self.value = _defaultValue
}
}
}
附录:相关资源:
- Autoclosure of self in initializers在 Swift 论坛中。
- SR-944 Cannot use 'self' in RHS of && before all properties are initialized错误报告。
引用错误报告:
Jordan Rose: This is true since && is implemented using @autoclosure, but it's certainly suboptimal.
关于swift - 'Constant captured by a closure before being initialized'错误是什么原因造成的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59449779/