尝试solve a problem目前无关紧要,我尝试在Swift中做一些在C#代码中非常正常的事情:定义一些协议来描述生产者 - 消费者关系,然后提供一个具体的实现制片人:
protocol Consumer
{
func someInterestingThing( producer: Producer )
func anotherInterestingThing( producer: Producer, happenedBefore: Bool )
}
protocol Producer
{
func addConsumer( consumer: Consumer )
func removeConsumer( consumer: Consumer )
}
class ConcreteProducer : Producer
{
private var _consumers = Set<Consumer>()
func addConsumer( consumer: Consumer ) {
_consumers.insert(consumer);
}
func removeConsumer( consumer: Consumer ) {
_consumers.remove(consumer);
}
}
这不起作用,因为我的Consumer
协议不是Hashable
,它必须是进入Swift Set
。 (在C#中,这没有出现,因为所有对象都继承了hashable-nature。)
好的,所以我将我的协议定义为继承自Hashable;不完全优雅,但应该工作。不!现在我使用它的所有地方,我得到:
error: protocol 'Consumer' can only be used as a generic constraint
because it has Self or associated type requirements
显然,这是因为Hashable
继承了Equatable
,它自己定义了==
。字面意思是Self
,其中{{}}}可以使用类型extra restrictions。
也许还有一些我不能理解的泛型魔法,这样我就可以使用编译器满意的类型来声明集合和方法?
我可能会尝试做一些有趣的事情,比如用更抽象的术语定义存储,并在添加和删除方法上强制执行协议一致性。但AnyObject
未实现Hashable
。 (有更好的选择吗?)
我可以尝试将消费者打包在一个实现Hashable
的私有包装器中,但是我需要能够比较这些包装器,这取决于消费者的身份,然后看起来像我回到了同一条船上。
我想要的只是将一堆这些东西放在一个集合中,而不再了解它们而不是绝对必要。我该怎么做?
答案 0 :(得分:1)
这个怎么样?
protocol Consumer: class {
func someInterestingThing( producer: Producer )
func anotherInterestingThing( producer: Producer, happenedBefore: Bool )
}
protocol Producer {
func addConsumer( consumer: Consumer )
func removeConsumer( consumer: Consumer )
}
class ConcreteProducer : Producer {
private var _consumers = [ObjectIdentifier:Consumer]()
func addConsumer( consumer: Consumer ) {
_consumers[ObjectIdentifier(consumer)] = consumer
}
func removeConsumer( consumer: Consumer ) {
_consumers[ObjectIdentifier(consumer)] = nil
}
}
Consumer
声明为class
仅协议Dictionary<ObjectIdentifier, Consumer>
代替Set<Consumer>