こんにちは!リンコですピヨ!この記事では自分の勉強の復習もかねて、Kotlinでの高階関数と匿名関数についてを記述する方法を解説するピヨ!
この第30章では、プログラミング言語であるKotlinの高階関数と匿名関数について、一緒に勉強していきましょう。
この記事を読めばプログラミング未経験の方も、Kotlin入門レベルの高階関数と匿名関数について1つ1つ理解しながら勉強できると思うので、是非最後まで読んで頂ければと思います。
※この記事で出てくる「サンプルコード」は、記述が長く画面からはみ出ている場合がありますが、横にスライドすると表示されるのでご安心ください。
【Kotlin】関数オブジェクトについて
本題の高階関数や匿名関数の話に入る前に、まずは「関数をオブジェクトとして扱う」ことに関して軽く説明していきます。
関数オブジェクトとは?
関数を変数に代入すること
今までは数値や文字などを変数に代入したりクラスを変数に代入してインスタンスとして使っていましたが、Kotlinでは関数も変数に代入することができます。
関数を変数に代入したものを「関数オブジェクト」と呼びます。
「::」という記号を使う
関数を変数に代入するには、関数名の前に「::」を付けます。詳しくは、関数オブジェクトの使用例を見ていきましょう。
関数オブジェクトは第一級オブジェクト
変数に代入できたり関数のパラメータとして扱えたり関数の戻り値として扱えるインスタンスやオブジェクトを、第一級オブジェクトと呼びます。
それと同様に、関数オブジェクトも関数のパラメータ、戻り値として扱えるので第一級オブジェクトです。
Kotlinでは関数も変数に代入することができるピヨ!
【Kotlin】実際に関数オブジェクトを使ってみよう
以下のサンプルコードを見て、実際に関数オブジェクトをどのように使うのか見ていきましょう。
サンプルコード
以下のサンプルコードでは「n + 1」という計算式の入った「oneAdd関数」を「::」を使って「変数add」に代入し、関数オブジェクトにして値を出力しています。
※コードがややこしくなり難しく見えてくるので、極力簡単なコードで説明しています
fun main(){ val add = ::oneAdd println(add(1)) } fun oneAdd(n: Int): Int = n + 1
出力
サンプルコードを実行すると、以下のように出力されます。
2
関数オブジェクトは「命令を書いた付箋」のようなイメージです。
例えば上司が「この資料を会議用に10枚印刷しておいて」と部下に「命令」したとします。この「命令」は定義済みの関数のようなものです。
上司がその「命令」をとある「付箋」に書き記したとします。この付箋は1つの物体として存在するので「インスタンス」とも言えます。
そしてその命令をインスタンス化した「付箋」が関数オブジェクトということになります。
このコードの場合は、n+1のoneAddが命令で、oneAddを代入した変数addが命令を書いた付箋という名の関数オブジェクトになります。
【Kotlin】高階関数と匿名関数について
ではここから本題の高階関数と匿名関数についての勉強に入ります。
高階関数とは?
まずは高階関数について説明していきましょう。
関数を受け取ったり、戻り値として返す関数
高階関数は、引数として関数を受け取ったり、戻り値として関数を返す関数のことを言います。
関数に関数を積み重ねているため、2階建てや3階建てのような建物構造に見立てて高階関数と呼ばれています。
匿名関数を使う
高階関数の引数として渡される関数では、匿名関数を使うのが主流となっています。詳しくは後程実際に記述していきます。
パラメータとして関数を受け取る、戻り値として関数を返す関数のことを高階関数と言うピヨ!
匿名関数とは?
続いて匿名関数について説明していきます。
名前のない関数
Kotlinでは、名前のない関数を定義することができるのですが、名前のない関数のことを匿名関数または無名関数と言います。
※この記事では匿名関数という名称で統一します
ラムダ式で使うのが主流
匿名関数は、変数への代入と関数定義を同時に行ったりするのですが、特にラムダ式で使うのが主流になります。
ラムダ式については、この後の章で勉強していきます。
匿名関数はラムダ式で使うことが多いピヨ!
【Kotlin】実際に高階関数と匿名関数を使ってみよう
高階関数と匿名関数はセットみたいなところがあるので、セットで一緒に記述して勉強していきます。
サンプルコード
以下のサンプルコードは、足し算と引き算を行うコードになります。
fun main(){ val value1 = getValue("plus") val value2 = getValue("minus") println(value1(100, 50)) println(value2(50,25)) } fun getValue(a: String) : (Int, Int) -> Int { val p = fun(num1: Int, num2: Int) = num1 + num2 val m = fun(num1: Int, num2: Int) = num1 - num2 val value = when(a) { "plus" -> p else -> m } return value }
出力
サンプルコードを実行すると、以下のように出力されます。
150 25
このコードの高階関数や匿名関数ですが、「getValue関数」が戻り値として別の関数を返している高階関数になります。
また、pやmが関数オブジェクトで、関数オブジェクトpやmに代入されている「fun(num1: Int, num2: Int) = num1 + num2」や「fun(num1: Int, num2: Int) = num1 – num2」が匿名関数です。
詳しく解説していくと、getValue関数がplusやminusと言った文字列のパラメータを変数aで受け取っています。
getValue関数はこの渡された文字列によって、別の動作をする関数オブジェクトpやmを返すようになっています。
getValue関数が返す値の型は「 (Int, Int) -> Int」です。これはパラメータに2つのInt型を受け取って、Int型の値を返す関数型ということです。
そしてmain関数で、getValueが返す値をvalue1とvalue2の2つの変数が受け取り、この2つの変数が関数として宣言されているかのように関数呼び出しができています。
なぜvalue1と2で関数の呼び出しができているかと言うと、getValueの中で関数オブジェクトpやmに匿名関数がセットされているからです。
この辺りはかなりややこしいですが、繰り返し勉強して覚えるようにしましょう。
まとめ
この記事では、プログラミング言語であるKotlinの高階関数と匿名関数について勉強していきましたが、いかがでしたでしょうか?今回の記事をまとめると以下のようになります。
- 関数を変数に代入することを関数オブジェクトと言う
- 「関数をパラメータとして受け取る関数」「関数を戻り値として戻す関数」が高階関数と言う
- 名前のない関数のことを匿名関数や無名関数と言う
- 高階関数や匿名関数はラムダ式で使う
今回勉強した「高階関数」や「匿名関数」はKotlinの入門レベルの知識になるので、何回も読み直してしっかり覚えておきましょう。
次回の記事では「ラムダ式」について勉強していくピヨ!
プログラミング未経験の方や入門レベルの方、Kotlinについて詳しくなりたい方は、また一緒に勉強するピヨ!
コメント