Kotlinでは、operatorキーワードを使用してオペレーターオーバーローディングがサポートされています。これにより、標準オペレーター(+, -, *, [], ==など)のカスタムタイプに対する独自のロジックを定義できます:
operator修飾子を付ける必要があります。例:
data class Vec2(val x: Int, val y: Int) { operator fun plus(other: Vec2) = Vec2(x + other.x, y + other.y) } val a = Vec2(1,2) val b = Vec2(2,3) val c = a + b // operator fun plusを呼び出す
ニュアンスとベストプラクティス:
==とequalsは一致している必要があります)。オペレーター
==のオーバーロードとメソッドequals()のオーバーライドは何が違いますか?
回答: Kotlinにおけるオペレーター==は常にメソッドequals()を呼び出します(nullチェックを行った後)。operator fun equals(other: Any?): Booleanを定義した場合、オペレーター==は常にそのメソッドを使用します。==とequals()が異なるように動作することはありません。
data class Point(val x: Int, val y: Int) { override operator fun equals(other: Any?): Boolean { ... } } val a = Point(1,2) val b = Point(1,2) println(a == b) // a.equals(b)を呼び出す
歴史
明示的な意味なしにオペレーターcompareToをオーバーロードした:
Pointクラスでoperator fun compareToを定義し、ソートで使用できるようにしました。しかし、「大きい」と「小さい」が明示的な意味を持たず、チームの異なるメンバーが異なるロジックを書いていました。結果は、コレクションのソート時の混乱したバグとなりました。
歴史
相互タイプのオペレーターの対称性を忘れた:
開発者はoperator fun plus(a: Matrix, b: Vector): Matrixを実装しましたが、Vector + Matrixの動作を確保しませんでした。対称関数を実装していなかったため、vector + matrixはコンパイルされず、matrix + vectorのみが動作しました。これにより、コードの多くの部分でバグが発生しました。
歴史
オペレーターgetの誤ったオーバーロード:
開発者はカスタムクラスを作成し、operator fun get(index: Int): Fooをオーバーロードしました。範囲外チェックを追加しなかったため、存在しない要素へのアクセスが無効なフィールドのオブジェクトを返し、例外をスローしませんでした。これがビジネスロジックに「見えない」エラーを引き起こしました。