非自明な閉鎖に使用することができない私は、静的な初期化メソッドを持つクラスを持っているしたいと思います:「自己」は
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() }
よりも複雑な任意の閉鎖のための型を推論することができません。たとえば、次のように解決策は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'
}
:
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()
}
閉鎖型を指定しようとすると、変数の型を明示的またはSelf
へA
からキャストエラーにつながります。
これはコンパイラの非常に不幸な制限のようです。それの背後に理由はありますか?この問題は将来のSwiftバージョンで修正される可能性がありますか?
これは同じではありませんが、これはhttp://stackoverflow.com/questions/25645090と非常によく似ています/ protocol-func-returning-selfとなります。基本的な問題は、Swiftはコンパイル時に 'Self'の型を判断する必要がありますが、実行時にそれを決定したいと思っています。コンパイル時にすべてを解決できるなら、クラス関数がSelfを実行できるように幾分拡張されていますが、Swiftはあなたの型が*これらのいくつかの場合に正しいものでなければならないと常に証明することはできません。それは実際には間違っている可能性があるからです)。 –
これはもう少し良くなると思っていますが、Swiftはこの種の複雑な継承を避けています(これらは非最終クラスなので、すべてのサブクラスを考慮する必要があります)。プロトコルは長期的に好きです。 Swift 4または5で完全に可能にしてください。 –
@RobNapier _Swiftは、これらのケースのいくつかであなたのタイプが正しくなければならないとは必ずしも証明できません(時にはそれがいかに未知であるか、そのような場合の例はありますか? –