2016-02-12 93 views
2

我是Swift的新手,我試圖用泛型來解決一些問題,但我遇到了奇怪的構建錯誤,我不明白。下面是示例代碼:Swift通用類型轉換?

class CJunk 
{ 
    var HowMuch:Int = 0 
} 

class CGarbage : CJunk 
{ 

} 

// This will not compile because: 
// Cannot convert return expression of type 'CGarbage' to return type 'T' 
func MakeGarbage<T:CJunk>(input:CJunk) -> T 
{ 
    let x: CGarbage = CGarbage() 
    x.HowMuch = input.HowMuch * 2; 
    return x; 
} 

OK,這似乎很奇怪,因爲CGargabe是CJunk ...讓我們嘗試一些更基本:

// Cannot convert return expression of type 'CJunk' to return type 'T' 
func MakeGarbage<T:CJunk>(input:CJunk) -> T 
{ 
    let x: CJunk = CJunk() 
    x.HowMuch = input.HowMuch * 2; 
    return x; 
} 

編輯: 的問題是,在每種情況下,我都錯誤地試圖向上傾斜。這實際上與泛型無關,而與OOP基本原理更相關。另一個問題是我誤解了錯誤信息。糟糕!

+0

''指定'T'是'CJunk'的(任意)*子類*,這就是爲什麼你不能返回CJunk或CGarbage的實例。 - 你想達到什麼目的? –

+0

不是關於Swift中的泛型,而是關於基本上每種語言中的泛型。例如,你的代碼也不能在Java中工作。 – luk2302

+0

@ A.R。第一個樣品還是第二個?第二個可能工作(不太熟悉C#泛型)。第一個不應該出於我在我的回答中提到的確切原因。 – luk2302

回答

1

什麼MartinR已經提到一點更明確提出:

<T:CJunk>意味着T之一CJunk非常具體子類。由於您嘗試返回CGarbageCJunk,因此無法保證返回的類實際上與特定的T匹配 - 它可能不可轉換。

你舉的例子是如此簡單泛型簡直是大材小用和容易的解決方案是完全放棄它們,因爲你的函數返回相同類型的所有時間任何方式:

func MakeGarbage(input:CJunk) -> CGarbage { 
    let x: CGarbage = CGarbage() 
    x.HowMuch = input.HowMuch * 2; 
    return x; 
} 

,我們將竭誠爲幫助解決更復雜的泛型問題 - 這個問題非常基本,根本沒有任何意義可以使用泛型。

如果你認爲你的泛型方法編譯器必須以某種方式推斷出類型T必須指定類型。編譯器無法首先推斷出它,如果你想知道最初的編譯器錯誤。因此你作爲開發者必須明確地提供T的類型。當你這樣做,並指定T必須實際上是YourSecondSubclass然後很容易明白爲什麼編譯器首先抱怨,因爲現在您的方法將返回CGarbage顯然不可轉換爲YourSecondSubclass。我希望這個解釋一下!?

考慮以下

class CJunk { var HowMuch:Int = 0 } 
class CGarbage : CJunk { } 
class MoreGarbage : CJunk { } 

func MakeGarbage<T:CJunk>(input:CJunk) -> T { 
    let x: CGarbage = CGarbage() 
    x.HowMuch = input.HowMuch * 2; 
    return x; 
} 

var more : MoreGarbage = MakeGarbage(CJunk()) 

編譯器沒有繼續並推斷TMoreGarbage因爲這是預期收益類型,遺憾的是沒有實際的返回類型CGarbage無關與MoreGarbage

此參數適用於兩種情況完全相同:編譯器推斷來電者的類型爲T,並且不能保證您可以將CJunk轉換爲T

+0

@ A.R。我對CJunk的第二個基地 - > CJunk不是100%肯定,我將在第一個案例中加入一點點澄清,並說明爲什麼它不被允許。 – luk2302

+0

@ A.R。我現在實際上完全明白了這一點;)我的例子是否更清楚一點?或者你還不確定? – luk2302

+0

@ A.R。不,它是根據調用者推斷出完全正確的類型,方法體對推導「T」並不重要,因爲它不應該這樣做。如果主體確定類型,那麼類型不需要是通用的。 – luk2302