ios - Swift:将子类类型的对象分配给具有泛型的基类类型的变量会产生错误

标签 ios swift generics inheritance

我想分配一个继承自其父类(BaseLectureViewController)的子类(TapWhatYouHearViewController) ) 使用继承类型 (TapWhatYouHear) 将泛型实现为父类 类型的变量 (BaseLectureViewController ) 与类型基类(游戏)的泛型。

Swift 产生以下错误:

Swift:: Error: cannot assign value of type 'TapWhatYouHearViewController' to type 'BaseLectureViewController?'

我读过,一个解决方案,例如在 Java 中会使用通配符泛型,但这在 Swift 中是不可能的。 还有其他解决办法吗?


这是我的设置:

/** GAME TYPES **/

enum GameType {
    case TapWhatYouHear,
    case ChooseTranslation
}

class Game {
    var title: String?
    var type: GameType?
}

class TapWhatYouHear : Game {
    var audio: String?
    var type: GameType = GameType.TapWhatYouHear
}

class ChooseTranslation : Game {
    var video: String?
    var type: GameType = GameType.ChooseTranslation
}

/** VIEW CONTROLLERS **/

class BaseLectureViewController<T: Game> {
   var game: T?
}

class TapWhatYouHearViewController : BaseLectureViewController<TapWhatYouHear> {

}

class ChooseTranslationViewController : BaseLectureViewController<ChooseTranslation> {

}

我想执行以下操作:

var game: Game = TapWhatYouHear() // <-- Depending on the user interaction, this can be any sub class of "Game"
var viewController: BaseLectureViewController<Game>

switch game.type {
    case .ChooseTranslation:
        viewController = TapWhatYouHearViewController() // <--Swift:: Error: cannot assign value of type 'TapWhatYouHearViewController' to type 'BaseLectureViewController<Game>?'
    case .TapWhatYouHear:
        viewController = ChooseTranslationViewController()
}

viewController.game = TapWhatYouHear()

我想做的是在运行时确定 BaseLectureViewController 的哪个子类应该分配给 viewController 变量。为了保存代码,我想将 Game 类型的游戏分配给 BaseLectureViewControllergame 属性。

最佳答案

您想到的通用方法是不可能的。我的建议是使用一个简单的继承解决方案,您可以在具体的 ViewController(即 TapWhatYouHearViewController)中覆盖 getGame() 并将游戏转换为您的特定类型。

import UIKit

enum GameType {
    case TapWhatYouHear
    case ChooseTranslation
}

class Game {
    var title: String?
    var type: GameType?
}

class TapWhatYouHear : Game {
    var audio: String?

    override init() {
        super.init()
        type = GameType.TapWhatYouHear
    }
}

class ChooseTranslation : Game {
    var video: String?

    override init() {
        super.init()
        type = GameType.ChooseTranslation
    }
}


/** VIEW CONTROLLERS **/



protocol Lecture {
    var game: Game? { get set }
}

class BaseLectureViewController: UIViewController, Lecture {

    var game: Game?
    func getGame() -> Game? {
        fatalError("Must be implemented in subclass")
    }
}

class TapWhatYouHearViewController : BaseLectureViewController {
    override func getGame() -> TapWhatYouHear? {
        return game as? TapWhatYouHear
    }
}

class ChooseTranslationViewController : BaseLectureViewController {
    override func getGame() -> ChooseTranslation? {
        return game as? ChooseTranslation
    }
}

var game: Game = TapWhatYouHear() // <-- Depending on the user interaction, this can be any sub class of "Game"
var viewController: BaseLectureViewController?

if let gameType = game.type {
    switch gameType {
    case GameType.ChooseTranslation:
        viewController = TapWhatYouHearViewController() // <--Swift:: Error: cannot assign value of type 'TapWhatYouHearViewController' to type 'BaseLectureViewController<Game>?'
    case GameType.TapWhatYouHear:
        viewController = ChooseTranslationViewController()
    }

    viewController?.game = TapWhatYouHear()
}



关于ios - Swift:将子类类型的对象分配给具有泛型的基类类型的变量会产生错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56443089/

相关文章:

c# - 获取通用列表中对象的索引

iOS 委托(delegate)崩溃

ios - 使用performSelectorInBackground时发生内存泄漏

iphone - iOS uiwebview 清除触摸事件历史记录

ios - 使用 segue 在 Swift 中的 ViewController 之间传递数据

java - 限制可以实现接口(interface)的类

iphone - 如何使用 NSXMLParser 查找 1 个元素

ios - swift - 绘制曲线时出错

swift - 大家好,有谁有使用 swift 将视频文件上传到 Amazon S3 的示例吗?

java - 无法将 char[] 传递给泛型方法