web-dev-qa-db-ja.com

Swiftのジェネリッククラスのtypealias

私は次のようにジェネリック型クラスの型エイリアスを作成しようとしています

class Cars<T> {
  ...
}

typealias SportCars = Cars

しかし、次のようにコンパイルエラーが発生しますReference to generic type 'Cars' requires argument in <...>

15
Encore PTL

あなたが発見したように、今のところ、ジェネリックでこれを行うことはできません。

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

Swiftプログラミング言語 iBookの章"Type Alias Declaration"実際にはどのタイプについては何も述べていませんcannot =エイリアス化されますが、単純にそのように見えます部分型(プレースホルダーが指定されていないジェネリックのように)は許可されていません。

これがSwiftでよいと思われる場合は、Appleにレーダー(バグレポート)を提出してください。

この答えを調べていると、部分的なタイプの問題が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
8
DarkDust

考えられる回避策は、型エイリアスをクラス/構造体にラップすることです。

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

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

typealiasとジェネリックスを使用できる最も遠い方法は、次のような特殊なタイプのエイリアスを作成することだと思います。

typealias SportsCar = Cars<Int>

同じジェネリック型に別の名前が必要な場合は、サブクラス化するだけです。

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

これは正確にはエイリアスではありませんが(Carsが予期される場合はSportCarsを使用できませんが、その逆は可能です)、「制御された」環境では機能します。でも私は自分を使いません。

2
Antonio