swift - 使用关联类型的 Swift 中的协议(protocol)一致性问题

标签 swift generics protocols

我无法使类符合使用associatedtype 的协议(protocol)。在 Playground 中,我输入了一个简短的示例来说明该问题:生产 ItemType 兼容项目的生产者和消费它们的消费者。如下:

protocol ItemType { }

protocol Producer: class {
    associatedtype T: ItemType
    func registerConsumer<C: Consumer where C.T == T>(consumer: C)
}

protocol Consumer: class {
    associatedtype T: ItemType
    func consume<P: Producer where P.T == T>(producer: P, item: T)
}

struct EmptyItem: ItemType { }

class DummyProducer: Producer {
    var consumer: DummyConsumer?

    func registerConsumer(consumer: DummyConsumer) {
        self.consumer = consumer
    }
}

class DummyConsumer: Consumer {
    func consume(producer: DummyProducer, item: EmptyItem) {
        print("Received \(item) from producer \(producer)")
    }
}

Xcode 警告我以下错误:

Playground execution failed: MyPlaygroundYeYe.playground:14:7: error: type 'DummyProducer' does not conform to protocol 'Producer'
class DummyProducer: Producer {
      ^
MyPlaygroundYeYe.playground:3:20: note: protocol requires nested type 'T'
    associatedtype T: ItemType
                   ^
MyPlaygroundYeYe.playground:22:7: error: type 'DummyConsumer' does not conform to protocol 'Consumer'
class DummyConsumer: Consumer {
      ^
MyPlaygroundYeYe.playground:9:10: note: protocol requires function 'consume(_:item:)' with type '<P> (P, item: EmptyItem) -> ()' (aka '<τ_1_0> (τ_1_0, item: EmptyItem) -> ()')
    func consume<P: Producer where P.T == T>(producer: P, item: T)
         ^
MyPlaygroundYeYe.playground:23:10: note: candidate has non-matching type '(DummyProducer, item: EmptyItem) -> ()' [with T = EmptyItem]
    func consume(producer: DummyProducer, item: EmptyItem) {
         ^

关于该问题的解决方案(如果存在)有什么建议吗?

最佳答案

您应该像这样定义类 DummyProducerDummyConsumer:

class DummyProducer: Producer {
    typealias T = EmptyItem

    func registerConsumer<C: Consumer where C.T == T>(consumer: C) {

    }
}

class DummyConsumer: Consumer {
    typealias T = EmptyItem

    func consume<P: Producer where P.T == T>(producer: P, item: T) {

    }
}

由于您在协议(protocol)定义中严格指定 associatedType TItemType,因此您不能仅使用 EmptyItem 在你的类中,因为 EmptyItem 不是唯一可以采用 ItemType 协议(protocol)的结构。

关于swift - 使用关联类型的 Swift 中的协议(protocol)一致性问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39369656/

相关文章:

swift - 如何使用 if-let 在 Swift 中进行类型删除?

ios - 按属性的第一个字母过滤

java - 执行 map-reduce 操作的通用方法。 (Java-8)

iphone - 委托(delegate)方法停止被调用(用于工作)

JSON金融协议(protocol)?

go - 如何通过http实现google的protocol buffers

ios - 拉动刷新和 View 上的事件指示器

java - 子类不能转换为通用父类

c# - 等效于 java 中的 C# 方法

swift - 如何创建自定义 NSCharacterSet?