不能使用协议来定义公共初始值设定项

Cannot use protocol to define common initializers

我正在尝试创建一个通用的 class,它能够将模型转换为其关联的视图模型。不幸的是,编译器不允许它并因以下错误而失败:

Cannot convert value of type 'Model' (generic parameter of generic class 'Store') to expected argument type 'ViewModel.Model' (associated type of protocol 'StoreViewModel')

我正在使用以下简化代码:

protocol StoreViewModel {
    associatedtype Model

    init(model: Model)
}

class Store<Model, ViewModel: StoreViewModel> {
    var models = [Model]()
    var results = [ViewModel]()

    func update() {
        results = models.map {
            ViewModel(model: [=11=])
            // Cannot convert value of type 'Model' (generic parameter of generic class 'Store') to expected argument type 'ViewModel.Model' (associated type of protocol 'StoreViewModel')
        }
    }
}

class Foo: NSManagedObject {}

class FooViewModel: StoreViewModel {
    var model: Foo
    required init(model: Foo) {
        self.model = model
    }
}

let store = Store<Foo, FooViewModel>()

我已经阅读过类型擦除,但我想知道没有更简单的解决方案来解决这个问题。

事实上,您当前的代码允许这样的事情:

let store = Store<Int, FooViewModel>()

显然这没有意义,但您的代码允许这样做,因为 Model 没有任何限制。 Model 可以是任何东西,不是吗?

让我们限制一下:

class Store<Model, ViewModel: StoreViewModel> where Model == ViewModel.Model {

现在我们看到拥有两个泛型参数是没有意义的!为什么要使用 Model,而我们只能使用 ViewModel.Model

class Store<ViewModel: StoreViewModel> {
    var models = [ViewModel.Model]()

或者,如果您讨厌长类型名称,请使用 typealias:

typealias Model = ViewModel.Model
var models = [Model]()