[Kotlin1.1-RC] Type aliasesの使い所

2017.02.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

まえがき

kotlin1.1でType aliasesができるようになったので、自分なり使い所を考えてみた。

First glimpse of Kotlin 1.1: Coroutines, Type aliases and more | Kotlin Blogの例ではこのようになっている。

typealias Length = Double
typealias Weight = Double

typealias Action<T> = (T) -> Unit
  • なぜDoubleやFloatを使わず、typealiasを使うのか
  • なぜclassやinterfaceを作らずに、typealiasを使うのか

自分なりに考えました。

なぜDoubleやFloatを使わず、typealiasを使うのか

単位を揃えたいときに有効なのではないでしょうか?

重さがDoubleっとなっていたら、実際g,kg,tどの単位でいれたらよいのか迷わないでしょうか?Doubleは値であって、単位を表してるわけではないと思います。例えば、Doubleをg(グラム)にするとわかりやすいと思います。さらにclass間で統一の単位に揃えることも簡単なので、このプログラム内ではgで統一するっということができます。

typealias g = Double
class Human(val weight: g)
class Car(val weight: g)

これを仮に小数点以下のgを入力しないっとなった場合は、定義の部分はgだけを修正すればよいのです。

typealias g = Int
class Human(val weight: g)
class Car(val weight: g)

応用の使い所になるのですが、拡張関数を用いるとさらに便利です。単位変換でとても有効です。

例えば、gをkgにしたいっとなったら、以下のようにすれば良いのです。Double

//拡張関数
fun g.kg() = this / 1000

//拡張プロパティ
val g.kg : Double get() = this / 1000

val human = Human(60000.0)
print(human.weight.kg)
print(human.weight.kg())

注意:gに拡張してますが、もとはDoubleなので、Doubleに拡張されているようです。利用するときには少し工夫が必要かもです

print(1000.0.kg)
print(1000.0.kg())

なぜclassやinterfaceを作らずに、typealiasを使うのか

コールバックのためだけにclass,interfaceを使用するのはめんどくさい!

Kotlinのおかげで、クラスを使わずラムダで記述することができました

fun execute(callback: ()-> Unit){
  callback()
}
execute{
  print("success")
}

()-> Unitっといちいち書くの面倒だし、これが何を表しているのかも変数名をみないと判断できない。

typealias SuccessCallback = () -> Unit
fun execute(callback: SuccessCallback){
  callback()
}

の方がよみやすいですね。

まとめ

Type aliasesは使い所が多そうです!