Swiftで型の別名を付ける事のできるtypealias
について調べてみました。
基本的な使い方
Intのaliasとして使います。
typealias MyInt = Int
let int: MyInt = 1
print(int)
print(int.value)
元のクラスにメソッドを追加した場合の動き
元のクラスであるIntに追加したメソッドは反映されます。
typealias MyInt = Int
extension Int {
func myMethod() {
print("My Method")
}
}
let int: MyInt = 1
print(int.myMethod())
Aliasの型
dynamicTypeで型を調べた所、元の型になりました。
typealiasの名前通り、Intの別名を作っているだけで実態は同じもののようです。
typealias MyInt = Int
let int: MyInt = 1
print(int.dynamicType) // → Int
関数のAlias
関数の別名を付ける事もできます。
メソッドの引数部分がすっきりするので、複雑な関数については別名を付けると良さそうです。
typealias MyBlock = () -> ()
func method(block: MyBlock) {
block()
}
タプルのAlias
タプルに対して別名を付ける事もできます。
簡単なアプリを作る際は、クラスの代わりにタプルを使うのも手軽で良さそうです。
typealias User = (id: Int, name: String)
let users = [
User(id: 1, name: "Name1"),
User(id: 2, name: "Name2"),
User(id: 3, name: "Name3"),
]
print(users.first!.id)
クラス内のtypealias
別クラス内で定義した型を使う場合はClassForAlias.MyInt
という形で利用する必要があります。
class ClassForAlias {
typealias MyInt = Int
}
class MyClass {
func method() {
ClassForAlias.MyInt.max
}
}
protocolのtypealias
protocol内でもtypealiasを使う事ができます。
protocol MyProtocol {
typealias MyInt = Int
}
class MyClass: MyProtocol {}
let int: MyClass.MyInt = 1
protocol内で宣言だけする事もできます。
その場合はそのprotocolを使うクラスで型の定義をする必要があります。
protocol MyProtocol {
typealias MyInt
}
class MyClass: MyProtocol {
typealias MyInt = Int
}
let int: MyClass.MyInt = 1
ややこしいですが、protocol内ではprotocolによる制限をかける事ができます。
protocol MyProtocol {
typealias MyInt: IntegerType // MyIntはIntegerTypeに準拠している必要がある
}
class MyClass: MyProtocol {
typealias MyInt = Int // typealias MyInt = Stringなどはできない
}
MyIntが特定の型の時だけextensionによるメソッド追加をする事ができます。
protocol MyProtocol {
typealias MyInt
}
class MyClass: MyProtocol {
typealias MyInt = Int
}
extension MyProtocol where MyInt == Int {
func method() {}
}
MyClass().method()
MyIntが特定のプロトコルを使ってるかどうかで絞り込みもできます。
protocol MyProtocol {
typealias MyInt
}
class MyClass: MyProtocol {
typealias MyInt = Int
}
extension MyProtocol where MyInt: IntegerType {
func method() {}
}
MyClass().method()
コメントで教えて頂いたのですが、この辺りはSwift3.0で一部キーワード名が変わるかもしれません。