2015-09-09

Kotlinことはじめ:(7)演算子オーバーライド

Kotlinでは演算子のオーバーロードをするために、演算子に対応する関数が用意されています。
演算子を使用すると、これらの関数の呼び出しに変換される仕組みです。
拡張関数の仕組みを使用することで、定義済みの型に対して演算子のオーバーロードをすることもできます。

この変換の仕組みのために、以下の一覧にある以外の記号を使った演算子を追加することはできません。
新たに追加する場合は、中置記法を用いて関数名を演算子のように使うことで可能になります。
ただし中置記法で再現可能なのは二項の演算子のみです。

単項演算子

値に符号をつける。
変換後
+a a.plus()
-a a.minus()
boolean値の反転。
変換後
!a a.not()
インクリメント/デクリメント。
変換後
a++ a.inc()
a— a.dec()
注意点として、inc()とdec()は元のオブジェクトの値を変更すべきではありません。
++/—は対象の前に置くことも、後ろに置くこともできるため、結果を返すだけの処理を書いていれば、前にあるか後ろにあるかによって、式が返すべき値が変わるため、変数への値の設定と戻り値が自動で制御されるためです。

二項演算子

いわゆる四則演算+剰余。
変換後
a + b a.plus(b)
a - b a.minus(b)
a * b a.times(b)
a / b a.div(b)
a % b a.mod(b)
四則演算+剰余の結果を代入。
変換後
a += b a.plusAssign(b)
a -= b a.minusAssign(b)
a *= b a.timesAssign(b)
a /= b a.divAssign(b)
a %= b a.modAssign(b)
等/不等式。
変換後
a == b a?.equals(b) ?: b.identityEquals(null)
a != b !(a?.equals(b) ?: b.identityEquals(null))
「===」「!==」はオーバーライドできません。
大小比較。
変換後
a > b a.compareTo(b) > 0
a < b a.compareTo(b) < 0
a >= b a.compareTo(b) >= 0
a <= b a.compareTo(b) <= 0
値の範囲。
変換後
a..b a.rangeTo(b)
「..」 「rangeTo」は値の範囲を示すオブジェクト(Rangeのインスタンス)を生成する演算子です。
内包チェック。
変換後
a in b b.cotains(a)
a !in b !b.contains(a)
内包チェックと値の範囲を組み合わせた
i in 1..10
という式は
1.rangeTo(10).contains(i)
のようになります。
配列の添字のようにオブジェクトから値を取得。
変換後
a[i] a.get(i)
a[i, j] a.get(i, j)
a[i_1, …, i_n] a.get(i_1, …, i_n)
a[i] = b a.set(i, b)
a[i, j] = b a.set(i, j, b)
a[i_1, …, i_n] = b a.set(i_1, …, i_n, b)
このおかげで、KotlinではMapから値を取得するのに、
val value = map[key]
のように書けます。
オブジェクト自体を関数のように呼び出す。
変換後
a(i) a.invoke(i)
a(i, j) a.invoke(i, j)
a(i_1, …, i_n) a.invoke(i_1, …, i_n)

0 件のコメント: