Swift通用类型转换?

问题描述:

我是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

什么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