Swift:Generic的类型协议无法识别

时间:2018-02-23 21:33:18

标签: swift generics protocols

长时间听众,第一次来电。

我收到以下错误:

Cannot convert value of type MyClass<Model<A>, OtherClass> to expected argument type MyClass<Protocol, OtherClass>

尽管MyClass<T>符合Protocol

我附加了一个可以在Playgrounds中运行的代码片段,类似于我实际尝试实现的内容。

protocol DisplayProtocol {
    var value: String { get }
}

class DataBundle<T: CustomStringConvertible>: DisplayProtocol {
    var data: T
    var value: String {
        return data.description
    }

    init(data: T) {
        self.data = data
    }
}

class Mapper<DisplayProtocol, Data> {
    // ...
}

class MapperViewModel<Data> {
    let mapper: Mapper<DisplayProtocol, Data>

    init(mapper: Mapper<DisplayProtocol, Data>) {
        self.mapper = mapper
    }
}

let dataBundle = DataBundle<Int>(data: 100)
let mapper = Mapper<DataBundle<Int>, Bool>()
let viewModel = MapperViewModel<Bool>(mapper: mapper) // <- This fails w/error

这是预期的行为吗?如果是这样,就会让我违反允许我在DisplayProtocol中将Mapper作为类型的合同。

1 个答案:

答案 0 :(得分:1)

这是因为Swift泛型在其参数方面是不变的。因此MyClass<B>MyClass<A>不兼容,即使BA(子类,协议一致性等)兼容。所以是的,不幸的是,这种行为是预期的行为。

在您的特定情况下,如果您想保留当前架构,则可能需要使用具有关联类型的协议并键入橡皮擦。