Part10: ラムダ式

ことり「今回は、高階関数とラムダ式のお話です」
凛「それより凛は伊豆のマリンパークへ行きたいにゃ!」
ことり「・・・凛ちゃん?」
凛「Aqoursの2ndPVがかっこよくて~」
ことり「ああ、Mermaid Festa Vol.3」
凛「・・・絶対違うにゃ」
ことり「Aqoursって、凛ちゃんと同じクラスだった子がいるんだよね」
凛「梨子ちゃん、あざといのはいいけどブラックぶりを発揮してないといいんだけど・・・」


高階関数

ことり「高階関数は、大抵の言語では使えると思うけど、関数を引数に取ったり関数を返したりする関数のことです」
凛「mapとかfilterとかsortとかよく見かけるにゃ」
ことり「よく使われる高階関数の代表格だね。あとは、コールバックの実装にもよく使われます」

ことり「もちろんKotlinでも高階関数を使うことができます」

ちゅんちゅん
にゃ

ことり「すごく単純な例だけど、kotori関数とかrin関数をhello関数に渡して実行させてるの」
凛「words: () -> Unitって何してるの?」
ことり「それは関数の型だよ」
凛「型?」
ことり「普通の引数と同じで、関数にも型があります。引数の数と型、戻り値の型が一致しないと渡せないの」
凛「えーっと、これは・・・引数なし、戻り値Unitってことかな?」
ことり「そうそう。ここは、たとえば(Int, String) -> Stringみたいに書いたりします」


ラムダ式

ことり「この例ではkotoriとかrinとかの関数を定義してそれを渡してたけど、いちいち関数定義をするのはちょっとめんどうだよね」
凛「ちょっとじゃないにゃ」
ことり「そこで登場するのが関数リテラル、ラムダ式とか無名関数です」

ちゅんちゅん
にゃ

ことり「{msg: String -> println(msg)}の部分がラムダ式。String型の引数を1つ取ってそれをwritelnで出力する関数を、funを使わずに書いてるんだよ」
凛「いちいち定義せずに渡せるって、こういうことなんだね」

ことり「ラムダ式で書いた関数は、変数に入れておくこともできるから再利用もできるの」

ことり「こんな感じ」
凛「関数もデータの1つっていうのは関数型言語の基本にゃ」
ことり「変数かラムダ式のどちらかに型が明示されていれば、もう片方は省略できるよ」

ことり「引数を1つしか取らないラムダ式は、さらに省略した書き方ができます」

ことり「引数がitという変数に入るから、引数を宣言しなくても書けるんだよ」
凛「おおっ、どんどん短くなっていくにゃ!」


無名関数

ことり「ラムダ式とよく似たものに、無名関数があります」

凛「なんか最初の関数定義に戻ったみたいだけど・・・」
ことり「ラムダ式にはね、戻り値の型を明示できないという問題があります。だいたいは文脈から判断できるんだけど、時々必要になることがあって」
凛「そっか、そういう場合にラムダ式の代わりに使うんだね」
ことり「fun(a: String, b: String): String = a + bって書くから、名前がない以外は単一行関数と同じって分かるよね」

ことり「気を付けないといけないのがreturnしたときの戻り先かな。Kotlinのreturnfunのブロックを抜ける動きをするから、無名関数はその関数自身、さっきの例ならpairを抜けて、ラムダ式はその外側の関数、helloを抜ける動きをします」
凛「むむ、これはちゃんと使い分けしないと変なことになりそうだにゃ」


クロージャ

ことり「ラムダ式の中からは、外側にある変数にアクセスできます」

3

凛「クロージャだね」


レシーバ付き関数リテラル

ことり「関数リテラルは、何かの型に対して『くっつける』みたいなことができます」

ことうみ

ことり「"こと".pair("うみ")みたいに、任意の文字列に対して関数を実行できるようになります」
凛「使い方が広がるにゃ!」
ことり「この機能は後で出てくる拡張関数とも似ています」


ことり「関数は次回でおしまい。インライン関数について見てみますね」
凛「あわしまマリンパークでゲストを招いて出張授業・・・」
ことり「だめっ!μ’sとAqoursの接触は、なんか大いなる意思みたいなのによって妨害されてるのっ!」


LINEで送る
Pocket


返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です