Swift泛型类型转换?

Swift泛型类型转换?,swift,generics,Swift,Generics,我是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

我是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;
}
CJunk类
{
变量多少:Int=0
}
CGarbage类:CJunk
{
}
//这将不会编译,因为:
//无法将“CGarbage”类型的返回表达式转换为返回类型“T”
func MakeGarbage(输入:CJunk)->T
{
设x:CGarbage=CGarbage()
x、 多少=输入。多少*2;
返回x;
}
好吧,这看起来很奇怪,因为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;
}
//无法将“CJunk”类型的返回表达式转换为返回类型“T”
func MakeGarbage(输入:CJunk)->T
{
设x:CJunk=CJunk()
x、 多少=输入。多少*2;
返回x;
}
编辑:
问题是,在每种情况下,我都错误地试图向上投射。这实际上与泛型无关,更多的是与OOP基础知识有关。另一个问题是我误解了错误消息。哎呀。

马丁纳已经说得更清楚了一点:

意味着
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())
class CJunk{var howmount:Int=0}
类CGarbage:CJunk{}
类:CJunk{}
func MakeGarbage(输入:CJunk)->T{
设x:CGarbage=CGarbage()
x、 多少=输入。多少*2;
返回x;
}
var more:moreargage=MakeGarbage(CJunk())
编译器no继续并推断
T
morebarbage
,因为这是预期的返回类型,不幸的是,实际返回的类型
CGarbage
morebarbage
无关


此参数对这两种情况的作用完全相同:编译器从调用方推断出
T
的类型,并且不能保证您可以将
CJunk
转换为
T
指定
T
CJunk
的(任意)子类,这就是为什么不能返回CJunk或CGarbage的实例你想实现什么?不是关于Swift中的泛型,而是关于基本上每种语言中的泛型。例如,您的代码在Java中也不能工作。@A.R.第一个示例还是第二个示例?第二种可能有效(对C#泛型不太熟悉)。第一个不应该适用于我在回答中提到的确切原因。@A.R.我不是100%确定关于CJunk->CJunk的第二个基础,我将对第一个案例以及为什么不允许它有更多的澄清。@A.R.我现在真的完全理解了;)我的例子是否更能说明这一点?还是你还不确定?@A.R.不,这是在推断完全正确的类型。。。基于调用者,方法体对于推断
T
并不重要,因为它不应该如此。如果主体将确定类型,那么类型不需要是泛型的。好吧,我错了。问题是,从技术上讲,我在每种情况下都试图向上投射,这就是为什么它会对我产生影响。不熟悉的语言错误消息和(主要是)我的沮丧让我意识到,代码在任何语言中都是非法的。很抱歉,我对此感到如此痛苦,我本应该更有耐心。@a.R.我理解这一点,但仍然认为这个问题很有道理-我个人认为,我会将编辑还原到原始问题,然后继续,也许新用户会偶然发现它,并理解他出了什么问题