vaguely

和歌山に戻りました。ふらふらと色々なものに手を出す毎日。

Kotlin Koansやってみたメモ Introduction編

はじめに

今月11月26日に2回目のKansai.ktが行われます。

kansai-kt.connpass.com

ワーパチパチ

ということで、今更ながらKotlin Koansにトライしてみました。
すると結構答えまで見ても内容がよくわからず、あれこれ調べてみたりしたのでそのあたりをまとめていきます。

いつも以上にあやふやな内容になるかと思いますので、正しくは公式ドキュメント赤べこ本など参照ということで。 (内容へのツッコミはお受けしますのでぜひどうぞm( )m)

Introduction - Extension functions

拡張関数について。

Int、Pairに対して有理数(RationalNumber)を返す「r」という関数を追加しています。
回答は下記です。

fun Int.r(): RationalNumber = RationalNumber(this, 1)
fun Pair.r(): RationalNumber = RationalNumber(first, second)

data class RationalNumber(val numerator: Int, val denominator: Int)

まず気になったのは、Int.r()にRationalNumberを渡すときの第二引数が1であること。
これは有理数の特徴である「分数であらわすことのできる数」を「第一引数/1」として元の値(第一引数)を変化させずに表現するため、ということのようです。

Pairは任意の2つの値を一纏めにするので、それぞれの値を第一、第二引数としています。
実際の利用には第二引数が0でないか、無理数でないかなどのチェックは必要そうです。

Introduction - Object expressions

オブジェクト式を使う問題。

回答はコチラ。

val arrayList = arrayListOf(1, 5, 2)
Collections.sort(arrayList, object : Comparator {
    override fun compare(x: Int, y: Int) = y - x
})

Comparator の compare を使って要素をソートしており、「y - x」の結果がマイナスの場合はyをxより前方に配置する、といった感じで並び替えを行います。

Introduction - SAM conversions

先程オブジェクト式を使ったコード、実は無名関数を使って以下のように書くこともできます。

val arrayList = arrayListOf(1, 2, 3)
Collections.sort(arrayList, { x, y ->
    y - x
})

Comparator の compareのように、オーバーライドする関数が一つだけ(Single Abstract Method: SAM)の場合はそれを省略して記述することができます。

なお、引数の型を明示することも可能です。

val arrayList = arrayListOf(1, 2, 3)
Collections.sort(arrayList, { x: Int, y: Int ->
    y - x
})

ただ、無名関数を使うと呼び出しのたびにインスタンスが作成されることになるため、一度しか実行されない場合を除き、オブジェクト式を使う方が良いようです。

別件ですが、無名関数の引数をカッコ「()」でくくる((x: Int, y: Int) -> のようにする)とエラーになります(下記コメントも参照)。

Introduction - Extension functions on collections

readonlyとmutableについて。

Listはreadonlyのため、下記のように後から要素を追加しようとするとエラーになります。

val arrayList: List = arrayListOf(1, 2, 3)
arrayList.add(0)

ただしImmutableではないので、ソートするなど値を変更することは可能です。というお話。

参考

有理数

Pair

オブジェクト式

Comparator

抽象メソッド