![](/img/trans.png)
[英]Downcast Generic AnyObject to Protocol Associated Type Self.Model
[英]Generic protocol with an associated type inheriting from AnyObject does not see another protocol as inheriting from AnyObject
假设我有一个称为Car的通用类绑定协议,该协议具有一个从AnyObject继承的关联类型。 该协议具有一个变量和一个定义的addPassenger()函数,并为其提供默认实现。
我需要关联的类型从AnyObject继承,因为我希望能够使用===过滤掉我在调用addPassenger()时已经知道的实例。
protocol Car: class {
associatedtype T: AnyObject
var passengers: [T] { get set }
func addPassenger(_ passenger: T)
}
extension Car {
func addPassenger(_ passenger: T) {
guard passengers.index(where: { $0 === passenger }) == nil else {
return
}
passengers.append(passenger)
}
}
然后,我还有另一个名为“乘客”的协议,该协议必须可与Car一起使用:
protocol Passenger: AnyObject {}
最后,假设我有一个名为SomeClass的类的实例,该类符合Car协议并定义了一系列Passengers:
class SomeClass: Car {
internal var passengers: [Passenger] = []
}
但是,这是不可能的,因为乘客显然不符合AnyObject:
error: type 'SomeClass' does not conform to protocol 'Car'
note: unable to infer associated type 'T' for protocol 'Car'
note: inferred type 'Passenger' (by matching requirement 'passengers') is invalid: does not conform to 'AnyObject'
知道我想念什么吗?
在实现协议时,必须将具体类型用作associatedType
。 我认为这与以下事实有关:用于通用类型的类型需要在编译时知道。 因此,您的案例由于以下原因而无法编译:
protocol A { }
class B: A { }
func f<T: A>(x: T) { }
// doesn't compile
let x: A = B()
f(x: x)
// compiles
let x = B()
f(x: x)
因为在编译时需要知道通用类型T。
在您的情况下,如果您希望SomeClass
使用符合Passenger
不同类型,则可以使用泛型使其工作:
class SomeClass<T: Passenger>: Car {
var passengers: [T] = []
}
或者,您当然可以改用基类
class BasePassenger: AnyObject {}
class SomeClass: Car {
var passengers: [BasePassenger] = []
}
希望这可以帮助! 祝好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.