Kotlinメモ

ちょっと真面目にkotlinを使いだしたので忘れないうちにイディオムとかをメモ書きしておく。感想としては、「書きやすいけどイディオムが多くてちょっと読みづらい言語」という感じ。慣れの問題…?

思いついたら適当に書き足していきます。

どうでもいいこと

スコープ関数

ここにまとまっている。わかりやすさのためRustとの対応を書いておく。

let hoge = {
    let mut hoge = Hoge();
    hoge.do_fuga();
    hoge.piyo = 1;
    hoge
};

val hoge = Hoge().apply { 
    doFuga()
    piyo = 1
}

みたいに書ける。alsoだとラムダ式としてバインドされるが、applyだけで事足りそう。他にも

let piyo = {
    let mut hoge = Hoge();
    hoge.piyo()
};

val piyo = Hoge().run {
    piyo()
}

となる。この場合alsoに対応するのはlet。(なおRustの例に関してはmutはあってもなくても同じだが個人的にはmutでなければわざわざスコープを掘らないかなあ。ただKotlinはmutabilityがアレなので使っていったほうがよさそう。)

クラス宣言

クラスのbodyとコンストラクタに区別があんまりないみたい。つまり、クラスを宣言すると自動的にコンストラクタも宣言したことになる。例えば

class Hoge {
    val fuga: String = "fugafuga".toUpperCase()
}

とかすると、{}の中はコンストラクタになっているのでこんな感じで定数以外の値も書ける。複数文は書けないが、alsoとかapplyとかを使えばよい。共通のinitialization処理とかをしたければinitブロックを使う。 で、このデフォルトコンストラクタ中で宣言された変数と関数はすべてクラスのメンバ変数・関数になる。なんか慣れないとちょっと気持ちわるいが、そういうもんだと思おう。メンバのvisibilityはデフォルトでpublic。「見えるけど変更されたくない」変数はセッタをprivateにする。

class Hoge {
    var fuga: String = "hoge"
    	private set
}

fun main() {
    val hoge = Hoge()
    println("${hoge.fuga}")
}

セカンダリコンストラクタを宣言したければconstructorキーワードで宣言する。ただしプライマリコンストラクタが非自明(引数あり)な場合、必ずプライマリコンストラクタを呼んでいなくてはならない。メンバ宣言がプライマリコンストラクタ中でなされているので当然なんだけど。なお、プライマリコンストラクタが自明(引数なし)であればimplicitに呼ばれる。

class Hoge(hoge: String) {
    val fuga: String = hoge.toUpperCase()
    
    constructor(): this("hoge")
    
    constructor(i: Int): this()  {
        println("${this.fuga}")
    }
}

fun main() {
    val hoge = Hoge(3)
}

こんな感じで間接的に呼ぶのでもよい。また、たとえ自明なコンストラクタがあったとしてもプライマリコンストラクタが非自明であれば明示的になにかのコンストラクタを呼ぶ必要がある。

Extension function

既存のクラスに勝手にメソッドとかを追加できる。別ファイルで定義した場合にprivate変数とかは読めない。Rustで言えば新しいtraitを定義して既存のstructimplする感じ。

getXX, setXX

kotlinのゲッタとセッタはgetXX, setXXというような関数にマングルされるみたい。そのため、pure JavaのクラスのgetXX, setXXを呼ぶ代わりにプロパティとしてアクセスできる。

import java.util.Calendar

fun main() {
    val c = Calendar.getInstance()
    val d = c.firstDayOfWeek
    println("${d}")
}

スタティックメソッドであるCalendar.getInstanceはちゃんと呼ばなければならなかった。 また、セッタは引数が複数個だとちゃんと呼ばなければならない。Boolean変数の場合、ゲッタセッタともにisXXXというプロパティになるらしい。

Wikipedia先生によるとアクセサとプロパティは現代の宗教論争みたい。個人的には何でもかんでもsyntax sugarで見えなくしてしまうのは好きではないなあ。(2000年代後半にC#を使わずに貧弱なJavaを使い続けた名残、、、かもしれない(笑)。ただRustもこういうたぐいのsyntax sugarは相当少ないほうなので、やっぱり嫌いな人はそれなりにいるんじゃないだろうか)

Comments

comments powered by Disqus