不能使用协议来定义公共初始值设定项
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]()
我正在尝试创建一个通用的 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]()