Swift中泛型类的类型别名

15
我试图创建一个泛型类型的typealias,代码如下:
class Cars<T> {
  ...
}

typealias SportCars = Cars

但我遇到了一个编译错误,如下所示:引用泛型类型“Cars”需要<...>的参数


1
什么是 Person?有代码缺失吗? - Antonio
抱歉,这只是一个虚构的例子和打字错误。但我的主要观点是如何为泛型类创建类型别名。 - Encore PTL
1
不确定为什么这个问题被投票否决了?有人能解释一下吗? - Encore PTL
这里使用typealias的目的是什么?为什么不使用子类化? - DarkDust
1
typealias 只是类的另一个名称,而子类化不允许我将 Cars 传递到需要 SportsCars 的地方。 - Encore PTL
3个回答

8

目前,正如你所发现的那样,使用泛型无法做到这一点。

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 )的协议的 typealias,但此时您会遇到一个问题,即 Swift 只允许您将这样的协议用作泛型约束 - 实质上与尝试使用部分类型相同的问题。 - Wes Campaigne

6

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

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

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

2

我认为在使用typealias和泛型时,最远能做到的就是创建一个特定类型的别名,例如:

typealias SportsCar = Cars<Int>

如果您需要为相同的通用类型使用不同的名称,只需对其进行子类化:

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

这并不完全是一个别名(当期望使用SportCars时,无法使用Cars,但反过来则是可能的),但在“受控”的环境中可以使用。虽然我个人不会使用。


我不想指定类型。这将限制SportsCar仅使用Int泛型类型。 - Encore PTL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接