You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift泛型类疑问:无法用MyClass作函数参数?MyClass<Any>不兼容MyClass<Int>?

Swift泛型类的两个常见问题解析

先看你定义的泛型类:

class MyClass<T> {
    
}

1. 为什么无法将MyClass用作函数参数?

你在f1里能写var b: MyClass = a,是因为编译器做了隐式泛型推断——它会根据右侧的MyClass<Int>实例,自动把b的实际类型推断为MyClass<Int>,并不是真的存在一个不带泛型参数的MyClass类型。

但函数参数的类型必须是明确的:编译器没办法从函数定义本身推断出你期望的泛型参数类型,也不能把这个推断的责任丢给函数调用者。所以直接写func f2(c: MyClass)时,编译器会报错,要求你显式指定泛型参数(比如<Any>)。

2. 为什么MyClass<Any>不接受MyClass<Int>?

这是因为Swift的泛型默认是非协变的。简单说:即使Int是Any的子类型,MyClass<Int>和MyClass<Any>也是完全独立的两个类型,彼此没有继承关系。

如果想让MyClass<Int>可以赋值给MyClass<Any>,需要把泛型类声明为协变的,也就是在泛型参数前加out关键字(仅适用于引用类型的泛型参数,且类的接口要符合协变要求——比如只向外暴露T类型的输出,不接受T类型的输入):

class MyClass<out T> {
    
}

修改后,MyClass<Int>就可以传入f3函数了。

补充:正确处理任意泛型类型的函数写法

如果你想让函数能接受任意类型的MyClass实例,更合适的方式是定义泛型函数,而不是用MyClass<Any>:

func f2<T>(c: MyClass<T>) {
    // 函数逻辑
}

这样不管是MyClass<Int>、MyClass<String>都能正常传入。

内容的提问来源于stack exchange,提问作者user_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 12:43:14