LoginSignup
9
3

More than 5 years have passed since last update.

愛は金よりも重い、そう Kotlin ならね

Posted at

なんか 金は愛よりも重い - Qiita という悲しい話題を見てしまいましたが、 Kotlin ならそんな悲しい現実も覆すことができます。

Kotlin は Web ブラウザ上で簡単にコードを実行できるツールが公式から出されているので、それを使って問題のコードを実行してみましょう。

kotlin_kane_ai.jpg

素晴らしい! Kotlin なら「愛」は「金」よりも重くなることが証明されました!






















説明

上のコードは、スクロールで見えなくなっているところも合わせると次のようになっています。

fun main(args: Array<String>) {
    println("'金' < '愛' = " + ("金" < '愛'))
    println("'愛' < '金' = " + ("愛" < '金'))
}



operator fun String.compareTo(c: Char) = c.toString().compareTo(this)

はい、 StringcompareTo() を生やして大小比較を逆転させています、ごめんなさい。

Kotlin には演算子オーバーロードがあり、 <compareTo() メソッドの実行に置き換えられます。
また、 Kotlin には拡張関数という、既存のクラスにメソッドを追加できる(ように見える)仕組みが用意されています。

つまり、 String に比較結果を逆転させる compareTo() メソッドを拡張関数で追加すれば、上のようなあべこべの結果を出すことができます。

しかし、 String にはすでに compareTo(String) という String 同士で比較しあうメソッドが定義されています。
拡張関数で追加したメソッドと同じシグネチャのメソッドが既にクラスに存在する場合、そのメソッドを実行しても拡張関数の方は実行されず、オリジナルのメソッドが必ず実行されます。

比較を逆転するよう拡張関数をcompareTo(String)で定義しても
fun main(args: Array<String>) {
    println("'金' < '愛' = " + ("金" < "愛"))
    println("'愛' < '金' = " + ("愛" < "金"))
}

operator fun String.compareTo(s: String) = s.compareTo(this)
実行されるのはオリジナルのcompareTo(String)なので、つらい現実が突きつけられる
'金' < '愛' = false
'愛' < '金' = true

ただ、拡張関数はオーバーロードは問題なく動きます。
そして、幸いにも? String には compareTo(Char) のメソッドは定義されていません

そこで、 compareTo(Char) のメソッドを拡張関数で定義し、 String"金"Char'愛' を比較することで、上のような結果を得ることができます。

以上、 Kotlin の拡張関数の間違った使い方でした。

9
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
3