我正在尝试使用通用"来练习#34;我遇到了2个错误:
通用参数' T'无法推断 参考泛型类型' GenericObject'需要< ...>
中的参数
GenericManager
级中的2个错误。请参考以下代码。我该如何解决这个问题?
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
}
}
class GenericObject<T> {
var items = [T]()
init(forType: T.Type) {}
func addObject(_ obj: T) {
self.items.append(obj)
}
}
class GenericManager {
//issue: Generic parameter 'T' could not be inferred
var objects = [GenericObject]()
//issue: Reference to generic type 'GenericObject' requires arguments in <...>
func addObject(_ obj: GenericObject) {
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)
答案 0 :(得分:2)
编译器需要知道T
的类型,在这种情况下,您还没有提供它。
你可以这样做:
var objects = [GenericObject<YourTypeHere>]()
例如,如果GenericObject
将包含Int
数组,则它将如下所示:
var objects = [GenericObject<Int>]()
我注意到您更新了问题。知道你想要实现的目标会很有帮助,但无论如何我都会尽力帮助你。
当你有一个通用对象时,你需要在编译时告诉编译器通用的类型,这就是为什么它抱怨不能推断出类型,它需要知道。
由于您希望能够将对象添加到GenericManager
数组,因此您需要在这两种情况下使用通用,因此您可以像这样修改您的类:
class GenericManager<T> {
var objects = [GenericObject<T>]()
func addObject(_ obj: GenericObject<T>) {
self.objects.append(obj)
}
}
但是,由于对象必须具有相同的通用,因此您无法将GenericObject<User>
和GenericObject<Employee>
添加到同一个经理,您可以做的是将其实现为{ {1}},并对GenericObject<Any>
执行相同操作,然后它将如下所示:
GenericManager
请记住,这将失去通用设备可以做的任何优势,你可以做的是创建一个协议或公共超类,而不是let u = User(name: "User")
let uo = GenericObject(forType: Any.self)
uo.addObject(u)
let e = Employee(name: "Employee", position: "session manager")
let eo = GenericObject(forType: Any.self)
eo.addObject(e)
let manager = GenericManager<Any>()
manager.addObject(uo)
manager.addObject(eo)
使用它,但这取决于你&#39;重新尝试实现。
如果您有任何其他问题,请添加评论,而不是默默地更新您的问题。
答案 1 :(得分:0)
您遇到的问题是您正在尝试使用泛型,但希望在GenericManager
中忽略它并存储对不同类型对象的引用。
考虑一下 - 当你致电manager.objects[0]
时,你期望什么回来?
你可以使用Any
进行类型擦除来解决这个问题,正如EmilioPelaez建议的那样。然而,这通常是一种代码,会导致整个代码中出现乱码。
一种替代方法是使用enum
指定您想要表示的不同类型的数据:
enum GenericObject {
case users([User])
case employees([Employee])
}
...
let uo = GenericObject.users([ u ])
...
let eo = GenericObject.employees([ e ])
现在,当您访问GenericManager
内的属性时,您需要切换不同的受支持类型,当您添加新类型时,只要您使用GenericObject
,就需要实现代码