且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Swift:将泛型类型转换为相同的泛型类型,但使用相关类型的子类

更新时间:2022-10-16 18:04:18

恐怕目前还不行可能从Swift 2.1开始。
$ b


  • 建立在集合类型中的元素类型是协变的。

  • 支持函数类型之间的转换,表现函数结果类型的协方差和函数参数类型的相反性。 (参见 Xcode 7.1发行说明



Objective-C的泛型支持类型方差,鉴于Swift 2.1中函数类型转换的进展,我相信有理由相信类型差异支持将在未来添加到Swift中。同时,请记住提交雷达,例如 jlieske



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



自从Swift变成开放以来的更新来源:
我相信完整的泛型 swift-30rel =nofollow> Swift 3.0开发路线图表示类型差异将在3.0中解决。虽然类型差异没有明确地被调出,但标准库中的特殊异常(包括类型差异)是。


Consider these classes:

struct OrderedSet<T: Hashable> {}

class Exercise: Hashable {}

class StrengthExercise: Exercise {}

class CardioExercise: Exercise {}

I'd like to do the following:

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
    }
}

But I get this error:

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

I don't quite get this, since StrengthExercise is a subclass of Exercise and will have everything that OrderedSet<Exercise> expects.

The question(s)

  • Why is this error necessary?
  • How to I write something that achieves the functionality I'm going for?



Radar filed
rdar://23608799


Blog post on covariance and contravariance
https://www.mikeash.com/pyblog/friday-qa-2015-11-20-covariance-and-contravariance.html

I am afraid this is not currently possible as of Swift 2.1. Only the following conversions are supported

  • Built in collections types are covariant on their element type.
  • Conversions between function types are supported, exhibiting covariance in function result types and contravariance in function parameter types. (Cf. Xcode 7.1 Release Notes)

As Objective-C's generics support type variance, and given the progress made on function type conversions in Swift 2.1, I believe there is reason to believe type variance support will be added to Swift in the future. In the mean time, remember to file a radar, like jlieske has.

In the mean time you will have to copy the collection or use one of the builtin collection types.

Update since Swift become open source: I believe the Complete generics section of Swift 3.0 Dev Roadmap indicates type variance will be addressed in 3.0. While type variance is not specifically called out, special cased exceptions in the standard library (which includes type variance) are.