2016/12/19の30分 Kotlinメモ🍭
2016/12/19の30分 Kotlinメモ🍭
書いてるコードは雑にここにあります。
Kotlinスタートブック -新しいAndroidプログラミング を引き続き読んでる。
Kotlinスタートブック -新しいAndroidプログラミング
- 作者: 長澤太郎
- 出版社/メーカー: リックテレコム
- 発売日: 2016/07/13
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る
Higher-Order Functions and Lambdas
関数オブジェクトとか関数型とか高階関数とかLambdaとかそこら辺の話。
前回読んだ時はちんぷんかんぷんだったけど、ちょっとわかってきたかも。
fun mumu(i: Int): Int { return i * 2 } // 関数オブジェクト val mumu = ::mumu println(::mumu) // 関数オブジェクトの型 // (引数の型) -> 戻り値の型 val mumu2: (Int) -> Int = ::mumu println(mumu(2))
Higher-Order Functions
関数を引数で受け取ったり、戻り値をして返すような関数を高階関数というらしい。
以下のように文字列から特定の条件にマッチした位置を返す関数があるとして、特定の条件ごとに関数を書いていくと。
fun firstK(str: String): Int { tailrec fun go(str: String, index: Int): Int = when { str.isEmpty() -> -1 str.first() == 'K' -> index else -> go(str.drop(1), index + 1) } return go(str, 0) } fun firstUpperCase(str: String): Int { tailrec fun go(str: String, index: Int): Int = when { str.isEmpty() -> -1 str.first().isUpperCase() -> index else -> go(str.drop(1), index + 1) } return go(str, 0) } println(firstK("aaaKaaa")) // 3 println(firstUpperCase("aaaAaaa")) // 3
特定の条件って部分を関数として受け取ればよくね?って話。なるほどー
// firstKとfirstUpperCaseの条件部分を関数オブジェクト化 fun first(str: String, predicate: (Char) -> Boolean): Int { tailrec fun go(str: String, index: Int): Int = when { str.isEmpty() -> -1 predicate(str.first()) -> index else -> go(str.drop(1), index + 1) } return go(str, 0) } fun firstK2(str: String): Int { fun isK(c: Char): Boolean = c == 'K' return first(str, ::isK) // 以下のように直で書いてもよい // return first(str, fun(c: Char): Boolean = c == 'K') // lambda式 // return first(str, { it == 'K' }) } fun firstUpperCase2(str: String): Int { fun isUpperCase(c: Char): Boolean = c.isUpperCase() return first(str, ::isUpperCase) // 以下のように直で書いてもよい // return first(str, fun(c: Char): Boolean = c.isUpperCase()) // 以下のように型を省略しても書ける // return first(str, fun(c) = c.isUpperCase()) // 以下のようにも書ける // return first(str, Char::isUpperCase) } println(firstK2("aaaKaaa")) // 3 println(firstUpperCase2("aaaAaaa")) // 3
Lambda
Lambdaなら一々::
とか書かなくても関数オブジェクト作れるよーって話。
it
便利!
// lambda式 // 関数オブジェクトを直接生成する val jijijiji: (Int) -> Int = { i: Int -> i * i } println(jijijiji(2)) // 4 // 型は省略できる val jijijiji2 = { i: Int -> i * i } println(jijijiji2(2)) // 4 // 引数が1つの場合、itを使える val jijijiji3: (Int) -> Int = { it * it } println(jijijiji3(2)) // 4
さらにLambdaを使って、文字列の中の最初の空白文字の位置を見つける関数を書いてみると。
fun firstWhitespace(str: String): Int = first(str, { it.isWhitespace() }) // 最後の引数がlambdaを取るような関数なら、以下にようにも書ける fun firstWhitespace2(str: String): Int = first(str) { it.isWhitespace() }
まとめ
雑な理解で雑なコードを書いていくぞい!!