4
使用我想有一類的靜態初始化方法:「自我」不能在不平凡的封閉
class A {
required init() {
}
// this one works
class func f0() -> Self {
return self.init()
}
// this one works as well
class func f1() -> Self {
let create = { self.init() } // no error, inferred closure type is '() -> Self'
return create()
}
}
不幸的是,斯威夫特3編譯器無法推斷類型,任何停業超過{ self.init() }
更復雜。例如:
class func f2() -> Self {
let create = {
// error: unable to infer complex closure return type; add explicit type to disambiguate
let a = self.init()
return a
}
return create()
}
任何嘗試來指定閉合類型,變量的類型顯式或從A
Self
到引線投射到一個錯誤:
class func f3() -> Self {
let create = {() -> Self in // error: 'Self' is only available in a protocol or as the result of a method in a class;
let a = self.init()
return a
}
return create()
}
class func f4() -> Self {
let create = {
let a: Self = self.init() // error: 'Self' is only available in a protocol or as the result of a method in a class;
return a
}
return create()
}
class func f5() -> Self {
let create = {() -> A in
let a = self.init()
return a
}
return create() as! Self // error: cannot convert return expression of type 'A' to return type 'Self'
}
解決方法是避免使用封閉Self
。
這似乎是編譯器的一個非常不幸的限制。背後有理由嗎?這個問題可能在未來的Swift版本中得到解決嗎?
雖然不完全相同,但它與http://stackoverflow.com/questions/25645090非常相似/協議FUNC-返回自。根本問題是Swift需要在編譯時確定'Self'的類型,但是你想在運行時確定它。它已經有所擴展,允許類函數運行Self,如果一切都可以在編譯時解決,但Swift不能總是證明你的類型*在某些情況下必須是正確的(有時是因爲它不知道如何但是,有時是因爲它實際上可能是錯的)。 –
我期望這會變得更好一些,但Swift不鼓勵這種複雜的繼承(這些是非最終類,所以你必須考慮所有可能的子類)並且更喜歡長期的協議,所以我不希望這樣做完全有可能在Swift 4或5. –
@RobNapier _Swift不能總是證明你的類型在某些情況下必須是正確的(有時是因爲它現在還不知道如何,有時候因爲它實際上可能是錯的) 。是否有這種情況的例子? –