Swift中“Generic parameter 'T' could not be inferred”错误及泛型类问题求解
解决泛型类使用中的两个编译错误
嘿,我来帮你搞定这两个泛型相关的编译错误!你遇到的这两个错误:
Generic parameter 'T' could not be inferred
Reference to generic type 'GenericObject' requires arguments in <...>
本质上是同一个问题,咱们一步步来解决。
错误原因分析
GenericObject是一个泛型类,编译器要求你必须明确它的泛型参数T具体是什么类型,不能直接把它当作普通的非泛型类来使用:
- 当你写
var objects = [GenericObject]()时,编译器无法推断出T的类型,所以抛出第一个错误; - 同理,方法参数
func addObject(_ obj: GenericObject)里的GenericObject没有指定泛型参数,编译器要求你必须在<>中补充类型,这就导致了第二个错误。
但你的需求是让GenericManager能同时存储GenericObject<User>和GenericObject<Employee>这类不同类型的泛型实例,所以不能直接指定某一个固定的T,这时候我们需要用类型擦除的技巧来解决这个问题。
解决方案:用非泛型协议实现类型擦除
我们可以定义一个非泛型的协议,让所有GenericObject<T>都遵守这个协议,这样GenericManager就可以用这个协议类型来存储任意类型的GenericObject实例,既保证了类型安全,又满足了存储不同泛型实例的需求。
修正后的完整代码
class User { var name: String init(name: String) { self.name = name } } class Employee { var name: String var position: String init(name: String, position: String) { self.name = name self.position = position } } // 定义一个非泛型协议,用于类型擦除 protocol AnyGenericObject {} // 让GenericObject遵守这个协议 class GenericObject<T>: AnyGenericObject { var items = [T]() init(forType: T.Type) {} func addObject(_ obj: T) { self.items.append(obj) } } class GenericManager { // 使用协议类型定义数组,能容纳任意GenericObject实例 var objects = [AnyGenericObject]() // 方法参数同样使用协议类型 func addObject(_ obj: AnyGenericObject) { self.objects.append(obj) } } // 测试代码完全正常运行 let u = User(name: "User") let uo = GenericObject(forType: User.self) uo.addObject(u) let e = Employee(name: "Employee", position: "session manager") let eo = GenericObject(forType: Employee.self) eo.addObject(e) let manager = GenericManager() manager.addObject(uo) manager.addObject(eo)
简化方案(如果不需要类型约束)
如果你只是需要存储这些实例,不需要在GenericManager中调用它们的泛型方法,也可以直接用[Any]来存储,代码会更简洁:
class GenericManager { var objects = [Any]() func addObject(_ obj: Any) { self.objects.append(obj) } }
不过这种方式的类型安全性稍弱,因为它允许存储任何类型的对象,而协议方式只能存储GenericObject的实例,更符合你的需求场景。
内容的提问来源于stack exchange,提问作者CocoaUser
相关产品推荐
相关产品推荐

