繁体   English   中英

具有从AnyObject继承的关联类型的通用协议不会将其他协议视为从AnyObject继承

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM