簡體   English   中英

無法將類型為'child'的返回表達式轉換為返回類型T.

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM