[英]Cannot convert return expression of type 'child' to return type T
我在Swift中與泛型有點掙扎。
我有以下代碼:
class Parent {
init(value: SomeThing) {
// ...
}
func clone<T: Parent>() -> T {
return T(value: SomeThing)
}
}
class Child : Parent {
var otherValue: SomeThingElse?
override func clone<T>() -> T where T : Parent {
let clone: Child = super.clone()
clone.otherValue = self.otherValue
return clone //ERROR: cannot convert return expression of type 'Child' to return type T
}
}
我們的想法是創建一個簡單的方法,該方法返回具有相同值的子實例的新副本。 我不想為每個Child classtype編寫構造函數。 (它在真正的課程中有很多參數,我喜歡保持干凈)。
我得到的錯誤是: cannot convert return expression of type 'Child' to return type T
建議的解決方案是使其return clone as! T
return clone as! T
但是這樣我就失去了使用泛型類的理由。
任何想法如何解決這個問題,同時保持它的通用性,而不是在每個類中寫出構造函數?
您需要具有Self
類型的返回類型,而不是使用約束為Parent
的通用占位符。 使用通用占位符,您可以說clone()
可以返回從Parent
繼承的任何特定具體類型的實例。 然而事實並非如此 - 您只想返回與接收器相同類型的實例,這就是Self
表達的內容。
然后,您還需要實現一個required
初始化程序,以便可以調用所有子類,允許在它們上調用clone()
,而不必覆蓋它。
struct Something {}
struct SomethingElse {}
class Parent {
var something: Something
required init(something: Something) {
self.something = something
}
func clone() -> Self {
// call the initialiser on the dynamic metatype of the instance,
// ensuring that we're instantiating a Self instance.
return type(of: self).init(something: something)
}
}
那么Child
的實現應該簡單如下:
class Child : Parent {
var somethingElse: SomethingElse?
override func clone() -> Self {
let clone = super.clone()
clone.somethingElse = somethingElse
return clone
}
}
然而不幸的是,在super
上調用clone()
返回一個靜態類型為Parent
而不是Self
的實例 - 這已被歸檔為bug 。
要解決這個問題,你必須做一些強制轉換hackery:
override func clone() -> Self {
let clone = super.clone() as! Child
clone.somethingElse = somethingElse
func forceCast<T>(_ value: Child) -> T { return value as! T }
return forceCast(clone)
}
嵌套的forceCast(_:)
函數在這里解決了我們當前無法在方法中直接forceCast(_:)
為Self
的事實(比較Swift中的Return instancetype )。 在這種情況下,強制轉換都將成功,因為super.clone()
將始終返回Self
實例,因此在此方法中必須是Child
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.