The reason for the error message is that the nil-coalescing operator
is defined as
public func ??<T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T
and does a "auto closure" on the second argument (in order to get
a short-circuiting behaviour). So
self.value = dict["bar"] as? String ?? _defaultValue
is transformed by the compiler to
self.value = dict["bar"] as? String ?? { self._defaultValue }()
and here the compiler complains because self
is captured before
being fully initialised. (The error messages are slightly different
between Swift 2 and Swift 3).
Possible workarounds. You can assign the property to a local variable first:
init(dict: NSDictionary){
let defValue = _defaultValue
self.value = dict["bar"] as? String! ?? defValue
}
Or you can make it a static property of the class:
class Foo {
static let _defaultValue = "N/A"
let value: String
init(dict: NSDictionary) {
self.value = dict["bar"] as? String ?? Foo._defaultValue
}
}
Or replace ??
by an if-statement:
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
}
}
}
Addendum: Related resources:
Quote from the bug report:
Jordan Rose: This is true since && is implemented using @autoclosure, but it's certainly suboptimal.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…