swift - 协议实例集合

  显示原文与译文双语对照的内容
0 0

我试图解决一个与目前无关的问题,我尝试用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,它必须进入一个快速的Set 。 ( 在 C# 中,这不会出现,因为所有对象都继承hashable属性。)

好,我将我的协议定义为从Hashable继承;不太优雅,但是应该能够。 不现在所有我使用的地方,我得到: !


error: protocol 'Consumer' can only be used as a generic constraint
because it has Self or associated type requirements

显然,这是因为 Hashable 继承了 Equatable,它本身定义了 == 。 根据 Self,它将一些额外限制放在了如何使用这种类型的方式上。

也许还有一些泛型魔术,我不认为这会允许我声明集合和编译器使用类型的方法。

我可以能尝试在更抽象的术语中定义存储,并且在添加和删除方法中执行协议一致性。 但是 AnyObject 没有实现 Hashable 。 ( 还有更好的选择)?

I 使用的方法,我可能会在实现 private 包装器中把消费者装箱,但是我需要能够比较那些依赖消费者身份的包装器,这似乎是我在同一个船上的。

我只需要在一个集合中保留一些这些东西,而不需要了解更多关于它们的信息。 我该怎么做?

时间: 原作者:

0 0

这个怎么样?


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>
...