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_
相关产品推荐
相关产品推荐

