简体   繁体   English

Swift中泛型类的类型

[英]typealias of generic class in Swift

I am trying to make a typealias of a generic type class as follows 我正在尝试按如下方式创建泛型类的类型

class Cars<T> {
  ...
}

typealias SportCars = Cars

but I am getting a compile error as follow Reference to generic type 'Cars' requires argument in <...> 但我得到一个编译错误,如下所示Reference to generic type 'Cars' requires argument in <...>

Right now, you can't do this with generics, as you've discovered. 现在,正如你所发现的那样,你不能用泛型做到这一点。

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

The Swift Programming Language iBook chapter "Type Alias Declaration" doesn't actually state anything about which types cannot be aliased. Swift编程语言 iBook章节“类型别名声明”实际上并未说明哪些类型不能别名。 But it simply looks like that partial types (like generics without placeholders specified) are not allowed. 但它看起来只是部分类型 (如没有指定占位符的泛型)不允许。

If you feel that this something Swift should do, file a Radar (bugreport) with Apple. 如果您觉得Swift应该做的事情,请向Apple提交Radar(bugreport)。

While researching for this answer, I noticed that the partial type problem not only affects typealias but is visible elsewhere as well: 在研究这个答案时,我注意到部分类型问题不仅影响了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! :-)

All of these work if you specify the placeholder types: 如果指定占位符类型,则所有这些都有效:

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

Possible workaround is to wrap type alias into class/struct: 可能的解决方法是将类型别名包装到class / struct中:

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

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

I think the farthest you can go with typealias and generics is to create an alias of a specialized type, such as: 我认为你可以使用typealias和泛型最远的方法是创建一个特殊类型的别名,例如:

typealias SportsCar = Cars<Int>

If you need a different name for the same generic type, you can just subclass it: 如果您需要相同泛型类型的不同名称,则可以将其子类化:

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

it's not exactly an alias (you cannot use Cars when SportCars is expected, but the opposite is possible), but in a "controlled" environment it can work. 它不完全是别名(当预期SportCars时你不能使用Cars ,但可能相反),但在“受控”环境中它可以工作。 I wouldn't use myself though. 我不会用自己的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM