【问题标题】:typealias of generic class in SwiftSwift 中泛型类的类型别名
【发布时间】:2014-07-13 13:58:51
【问题描述】:

我正在尝试如下制作泛型类型的类型别名

class Cars<T> {
  ...
}

typealias SportCars = Cars

但我收到如下编译错误Reference to generic type 'Cars' requires argument in &lt;...&gt;

【问题讨论】:

  • Person 是什么?是否缺少代码?
  • 抱歉,它是虚构的示例和错字。但我的主要观点是如何制作泛型类的类型别名
  • 不确定为什么这个问题被否决?谁能解释一下?
  • 这里的 typealias 有什么意义?为什么不子类化?
  • typealias 只是一个类的另一个名称,因为子类化不允许我通过需要 SportsCars 的 Cars。

标签: swift xcode6


【解决方案1】:

正如你所发现的,现在你不能用泛型来做到这一点。

typealias Foo = Array
// Doesn't work: Reference to generic type 'Array' requires argument in <...>

Swift 编程语言 iBook 章节“类型别名声明” 实际上并没有说明哪些类型不能 被别名。但它只是看起来不允许部分类型(如没有指定占位符的泛型)。

如果您认为这是 Swift 应该做的事情,请向 Apple 提交 Radar(错误报告)。

在研究这个答案时,我注意到 部分类型 问题不仅影响typealias,而且在其他地方也可见:

let foo = Array.self
// Doesn't work: Cannot convert the expression's type 'Array<T>.Type' to type 'Array<T>.Type'
// … which is a very confusing error.

var bar: Array.Type
// Doesn't work: Reference to generic type 'Array' requires arguments in <...>

let bar: Array.Type = Array.self
// …/usr/bin/swift: Segmentation fault! :-)

如果您指定占位符类型,所有这些都可以工作:

typealias Foo = Array<Int> // Works
let foo = Array<Int>.self // Works

【讨论】:

  • 一个伪替代方案:您可以创建一个包含相关类型要求的协议的typealias(即,实现可以映射到泛型的嵌套typealiases),但随后您会遇到Swift 只允许您将此类协议用作泛型约束的问题——本质上与尝试使用部分类型的问题相同。
【解决方案2】:

可能的解决方法是将类型别名包装到类/结构中:

struct SportCars<Y> {
  typealias T = Cars<Y>
}

/// Usage:
typealias Foo = SportCars<Int>.T

【讨论】:

    【解决方案3】:

    我认为使用typealias 和泛型可以走的最远的地方是创建一个特殊类型的别名,例如:

    typealias SportsCar = Cars<Int>
    

    如果您需要为同一个泛型类型使用不同的名称,您可以将其子类化:

    class SportCars<T> : Cars<T> {}
    

    它不完全是别名(当预期 SportCars 时,您不能使用 Cars,但相反的情况是可能的),但在“受控”环境中它可以工作。不过我不会使用自己。

    【讨论】:

    • 我不想指定类型。这将 SportsCar 限制为仅 Int 泛型类型。
    猜你喜欢
    • 1970-01-01
    • 2016-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-27
    相关资源
    最近更新 更多