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基本原理更相关。另一个问题是我误解了错误信息。糟糕!
答
什么MartinR已经提到一点更明确提出:
<T:CJunk>
意味着T
是之一CJunk
非常具体子类。由于您尝试返回CGarbage
或CJunk
,因此无法保证返回的类实际上与特定的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())
编译器没有继续并推断T
是MoreGarbage
因为这是预期收益类型,遗憾的是没有实际的返回类型CGarbage
无关与MoreGarbage
。
此参数适用于两种情况完全相同:编译器推断来电者的类型为T
,并且不能保证您可以将CJunk
转换为T
。
''指定'T'是'CJunk'的(任意)*子类*,这就是为什么你不能返回CJunk或CGarbage的实例。 - 你想达到什么目的? –
不是关于Swift中的泛型,而是关于基本上每种语言中的泛型。例如,你的代码也不能在Java中工作。 – luk2302
@ A.R。第一个样品还是第二个?第二个可能工作(不太熟悉C#泛型)。第一个不应该出于我在我的回答中提到的确切原因。 – luk2302