[英]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.