如何在Swift的泛型中声明基类?

时间:2018-11-29 12:58:36

标签: ios swift generics mvvm

无法正常工作的代码示例,但我想成功编译它。在下面的源代码中很好地描述了想法。您可以轻松地将其粘贴到Swift游乐场。

import UIKit

// MARK: - Base classes with generics

class FlowController {

}

class ViewModel<FlowControllerType: FlowController> {
    let flowController: FlowControllerType
    init (flowController: FlowControllerType) {
        self.flowController = flowController
    }
}

class ViewController<ViewModelType: ViewModel<FlowController>> {

    var viewModel: ViewModelType!
}

// MARK: - My implementation

class MyFlowController: FlowController {

}

class MyViewModel: ViewModel<MyFlowController> {
    override init (flowController: MyFlowController) {
        super.init(flowController: flowController)
    }
}

// ERROR: 'ViewController' requires that 'MyModelView' inherit from 'ViewModel<FlowController>'
class MyViewController: ViewController<MyViewModel> {

}

// MARK: - Code

let viewController = MyViewController()
viewController.viewModel = MyViewModel(flowController: MyFlowController())

问题是我想声明MyViewController,但出现错误:

'ViewController' requires that 'MyModelView' inherit from 'ViewModel<FlowController>'

问题是如何声明这些类以使其起作用?我应该为此使用where子句吗?我想在基类中为ViewController.viewModelViewModel.flowController拥有自己的类型,以保持类之间的这些依赖关系。预先谢谢你。

相关问题: Swift generic inheritance

1 个答案:

答案 0 :(得分:3)

我可能已经回答了,但是看起来比这个解决方案更好。技巧在下一行

class ViewController<FlowControllerType: FlowController, ViewModelType: ViewModel<FlowControllerType>> {

应代替

class ViewController<ViewModelType: ViewModel<FlowController>> {

我希望其他人可以做得更好,但目前仅此有效。完整的游乐场示例:

import UIKit

// MARK: - Base classes with generics

class FlowController {

}

class ViewModel<FlowControllerType: FlowController> {
    let flowController: FlowControllerType
    init (flowController: FlowControllerType) {
        self.flowController = flowController
    }
}

class ViewController<FlowControllerType: FlowController, ViewModelType: ViewModel<FlowControllerType>> {

    var viewModel: ViewModelType!
}

// MARK: - My implementation

class MyFlowController: FlowController {

}

class MyViewModel: ViewModel<MyFlowController> {
    override init (flowController: MyFlowController) {
        super.init(flowController: flowController)
    }
}

class MyViewController: ViewController<MyFlowController, MyViewModel> {

}

// MARK: - Code

let viewController = MyViewController()
viewController.viewModel = MyViewModel(flowController: MyFlowController())