ios - Swift:将泛型类型转换为相同的泛型类型但具有关联类型的子类

标签 ios swift macos generics inheritance

考虑这些类:

struct OrderedSet<T: Hashable> {}

class Exercise: Hashable {}

class StrengthExercise: Exercise {}

class CardioExercise: Exercise {}

我想做以下事情:

var displayedExercises = OrderedSet<Exercise>() {
    didSet {
        self.tableView.reloadData()
    }
}
var cardioExercises = OrderedSet<CardioExercise>()
var strengthExercises = OrderedSet<StrengthExercise>()


@IBAction func segmentControlChanged(segmentControl: UISegmentedControl) {
    switch segmentControl.selectedSegmentIndex {
    case 0:     self.displayedExercises = self.strengthExercises
    case 1:     self.displayedExercises = self.cardioExercises
    default:    break
    }
}

但是我得到这个错误:

Cannot assign value of type 'OrderedSet<StrengthExercise>' to type 'OrderedSet<Exercise>

我不太明白,因为StrengthExerciseExercise 的子类并将拥有OrderedSet<Exercise>的一切期待。

问题

  • 为什么需要这个错误?
  • 如何编写实现我想要的功能的东西?



雷达归档
rdar://23608799


关于协变和逆变的博文
https://www.mikeash.com/pyblog/friday-qa-2015-11-20-covariance-and-contravariance.html

最佳答案

恐怕这在 Swift 2.1 中是不可能的。仅支持以下转换

  • 内置集合类型在其元素类型上是协变的。
  • 支持函数类型之间的转换,表现出函数结果类型的协变和函数参数类型的逆变。 (参见 Xcode 7.1 Release Notes)

由于 Objective-C 的泛型支持类型变化,并且考虑到 Swift 2.1 在函数类型转换方面取得的进展,我相信有理由相信 Swift 将来会添加类型变化支持。与此同时,记得提交一个雷达,比如 jlieske has .

与此同时,您将不得不复制集合或使用其中一种内置集合类型。

自 Swift 开源以来的更新: 我相信 Swift 3.0 Dev Roadmap完整泛型部分表示类型差异将在 3.0 中解决。虽然没有特别指出类型差异,但标准库(包括类型差异)中的特殊情况异常(exception)。

关于ios - Swift:将泛型类型转换为相同的泛型类型但具有关联类型的子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33752968/

相关文章:

macos - 警告 : Plotting with an 'unknown' terminal. 将不会生成任何输出。请选择带有 'set terminal' 的终端

ios - cooking 书应用程序的自定义 iOS View

ios - 隐藏 textView 光标

ios - WCSession 发送消息在实际设备上不起作用,但在模拟器上起作用

ios - 通过 iOS 上的 &lt;input type=file> 上传存储在云服务上的 0 字节文件

ios - 无法在 iOS 中播放 amr 音频文件

swift - 为什么类型推断在 Swift 3 的这个 switch 语句中不起作用?

ios - 如何在 View Controller Storyboard初始化期间注入(inject) View 模型?

macos - .dylib 动态链接库可以打包成可执行文件吗?

objective-c - 带有可见控件的透明 NSWindow