![](/img/trans.png)
[英]Crash when found nil while implicitly unwrapping an Optional value that is not nil
[英]Crash on unwrapping nil optional
我創建了一個新的運算符,只有當值不為nil時才將值與目標關聯,否則不執行任何操作。 基本上它是合成糖, if let foo = foo { faa = foo }
:
infix operator =? {}
func =?<T>(inout lhs: T, rhs: T?) {
if let rhs = rhs {
lhs = rhs
}
}
func =?<T>(inout lhs: T?, rhs: T?) {
if let rhs = rhs {
lhs = rhs
}
}
這樣我可以節省一些打字:
// instead this:
if let x = maybeX {
z = x
}
// I can do this:
z =? x
我的問題是,當我到達執行線( z =? x
)時,我甚至在進入實現函數之前崩潰,但異常:
fatal error: unexpectedly found nil while unwrapping an Optional value
似乎Swift試圖強制解包x
即使實現接受T?
。
有任何想法嗎?
這似乎是我的錯誤......我正在使用foo.z = ...
其中foo
是一個零UIImageView!
...來自筆尖的致命視圖......
我很樂意在@RMenke建議后使用nil合並運算符更改我的實現,但據我所知,這將導致在x為nil時將z設置為z的冗余操作...例如:
var z = someFoo()
var x: Int? = nil
z = x ?? z
// will this re-write z's reference to z again or simply do nothing?
@MartinR發表了重要評論:
如果運算符(或函數)接受inout參數,則即使您未在運算符內分配新值,也會在返回時調用屬性setter
為了解決這個問題,我將以下擴展作為_ = foo.map...
方法的更清晰版本:
extension Optional {
public func use<U>(@noescape f: (Wrapped) throws -> U) rethrows {
_ = try self.map(f)
}
}
//then:
x.use{ z = $0 }
它可能更好,因為當x為零時它不會調用z的setter,但它是最干凈/最清晰的方式嗎?
您的運營商有效,但您應該使用鏈式選項:foo?.z = ...
但是,當foo為nil時,這會給你另一種錯誤,你可以通過添加來解決
func =?<T>(lhs: T??, rhs: T?) -> ()
{}
操作符的“無操作”版本吸收了在傳遞最后一個成員之前具有nil的可選鏈時獲得的不可變參數版本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.