Kotlinでは、数値型の計算 1 + 1 のような記法を任意のクラスでも使うことができる演算子オーバロードという機能が提供されています。
演算子オーバロードを使うことで、コードのシンプルさが高まります。
基本
Kotlinのソースコードを見ると、Int型やArray型でも演算子オーバロードが使われています。
public final class Int : kotlin.Number, kotlin.Comparable<kotlin.Int> {
...
public final operator fun plus(/*0*/ other: kotlin.Int): kotlin.Int {
...
}
}
Int型ではoperatorをオーバロードしている plus メソッドにより以下のように書くことができます。
val num = 1 + 1
public class Array<T> : Cloneable {
...
public operator fun get(index: Int): T {
...
}
}
Array型ではoperatorをオーバロードしている get メソッドにより以下のように書くことができます。
val array = arrayOf(0, 1, 2)
val i = array[0]
演算子オーバーロード
ここでは、任意のクラスで利用できる演算子オーバロードの一覧を記載します。
単項演算
| 演算子 | 関数 |
|---|---|
| +a | a.unaryPlus() |
| -a | a.unaryMinus() |
| ! | a.not() |
インクリメント・デクリメント
| 演算子 | 関数 |
|---|---|
| a++ | a.inc() |
| a-- | a.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.rangeTo(b) |
| a in b | b.contains(a) |
| a !in b | !b.contains(a) |
| 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[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) |
比較
| 演算子 | 関数 |
|---|---|
| a == b | a?.equals(b) ?: b === null |
| a != b | !(a?.equals(b) ?: b === 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() | a.invoke() |
| a(i) | a.invoke(i) |
| a(i, j) | a.invoke(i, j) |
| a(i_1, ..., i_n) | a.invoke(i_1, ..., i_n) |
実装例
ListViewの行にカスタムレイアウトを使う場合、BaseAdapterを継承したカスタムAdapterを作成するかと思います。
Adpterクラスからアイテムを取得する場合、既存のコードだと以下のようになります。
val adapter = ...
val item = adapter.getItem(0)
このコードをシンプルするために演算子オーバロードを使ってBaseAdapterクラスを拡張します。
operator fun BaseAdapter.get(position: Int): Any = getItem(position)
アイテム取得のコードが以下のようにシンプルになります。
val adapter = ...
val item = adapter[0]
おわりに
演算子オーバロードを使うことで、既存のコードをシンプルかつ読みやすくすることができるかと思います。
他に面白い使い方がありましたらご教授お願い致します!