我收到编译错误:
二元运算符'==='不能应用于两个'T'操作数
其中T是泛型类型,我只是比较两个类型为T的项目。
所以我认为我需要告诉它,通过使T扩展协议,可以在T上使用===
运算符。如果是==
我会使用Equatable
,但我无法看到我应该用于身份比较。
或者有解决方法吗?
编辑:
以下是说明问题的示例代码。我在这里添加了'AnyObject',它在实例化类时导致编译错误。如果删除'AnyObject',则会在'==='上导致错误。
import Foundation
protocol Messenger : AnyObject {
func notify();
}
class PostOffice<T : AnyObject> {
var messengers : [T] = []
func addMessenger(messenger : T) {
messengers.append(messenger)
}
func deleteMessenger(messenger : T) {
for i in 0 ..< messengers.count {
if messengers[i] === messenger { // error if AnyObject not used
messengers.removeAtIndex(i)
return
}
}
}
func handleDelivery(messenger : T) {} // to be overridden
func deliver() {
for messenger in messengers {
handleDelivery(messenger)
}
}
}
let p : PostOffice<Messenger> = PostOffice<Messenger>() // error if AnyObject used
这种情况下的错误是:
使用'Messenger'作为符合'AnyObject'的具体类型不支持。
答案 0 :(得分:2)
如果你看一下public func ===(lhs: AnyObject?, rhs: AnyObject?) -> Bool
的定义方式:
public func ===<L : AnyCollectionType, R : AnyCollectionType>(lhs: L, rhs: R) -> Bool
和
T
您可以看到确保AnyObject
符合AnyCollectionType
或func f<T : AnyObject>(a: T, b: T) -> Bool {
return a === b
}
的要求。例如:
func f<T : AnyCollectionType>(a: T, b: T) -> Bool {
return a === b
}
或
{{1}}
答案 1 :(得分:1)
您正在以一种无意义的方式混合泛型和协议。
class PostOffice<T : AnyObject> {
这意味着您希望PostOffices成为某些特定类型的包装器。不是“任何符合这种和这样的协议的类型”,而是一种类型,一种类型。好的,没关系。
let p : PostOffice<Messenger> = PostOffice<Messenger>() // error if AnyObject used
这表示您希望p
成为PostOffice
,它包含恰好符合Messenger
的任何类型。好吧,那不是你想要的PostOffice
。你说你希望它是类型专用的。那是什么?
根据您的命名,我假设您确实希望PostOffice
接受任何Messenger
。那没关系,但那不应该是通用的:
class PostOffice {
var messengers : [Messenger] = []
func addMessenger(messenger : Messenger) {
messengers.append(messenger)
}
func deleteMessenger(messenger : Messenger) {
for i in 0 ..< messengers.count {
if messengers[i] === messenger { // error if AnyObject not used
messengers.removeAtIndex(i)
return
}
}
}
func handleDelivery(messenger : Messenger) {} // to be overridden
func deliver() {
for messenger in messengers {
handleDelivery(messenger)
}
}
}
那就是说,你没有在任何地方使用notify()
,这听起来你真的希望PostOffice
能够在非信使上工作。 (不确定这有用,但它似乎是你写的)。那也没关系,但是你需要一些你专注于PostOffice
的实际类型(不是协议):
class SomeMessenger: Messenger {
func notify() {}
}
let p = PostOffice<SomeMessenger>()
如果您的意思是PostOffice
应该是专门的,但在这种情况下您希望接受任何类型的Messenger
,那么您需要type-erasure以便您可以创建具体类型包裹Messenger
:
final class AnyMessager: Messenger {
let _notify: () -> Void
init(messenger: Messenger) {
_notify = messenger.notify
}
func notify() { _notify() }
}
let p = PostOffice<AnyMessager>()
(这是许多Swift协议问题的解决方案,但在这种情况下感觉不对。我怀疑你真的希望PostOffice
要求Messenger
。但我不是真的理解你的PostOffice
类型。它将泛型与抽象类混合在一起,这并不是很真实。我怀疑你真的想重新设计这些类型。)
您可能对this implementation of an Observable感兴趣。它显示了一种注册和删除侦听器的不同方法,无需===
或notify
方法。