Kotlin 関数　省略方法（ラムダや高階関数など・・・）

※プログラミング初心者です。

Kotlinを勉強中なのですが、以下の二つの点から、ここでアウトプットを増やしていこうと思っております。

- 知識の定着
-  自分なりのコード理解への流れを可視化
-  競技プログラミングでの他人のコードを理解するため
-  文章を書くことに慣れる

では、早速・・・・・

##　関数内で省略ができること

### 関数をオブジェクト化する

簡単な足し算でやってみます。

関数を「オブジェクト化」するということは、**「インスタンス化」**と同じと考えて良い。
**スコープ内のコード量を減らすなど、リファクタリングに役立つ（らしい・・・）**


```kotlin:sample.kt
fun addition(n: Int) = n + 1

fun main(){
   val ownFunction =  addition(5)
   println(ownFunction)  //-> 6
}

```

これがいつもの感じ・・・・
これだと、addition関数の返り値が変数に入るようになる。

ここで、変数の中に関数をいれるようにする


```kotlin:sample.kt
fun addition(n: Int) = n + 1

fun main(){
   val ownFunction =  ::addition // -> ここが変化
   val ans = ownFunction(5) //-> 変数が関数化している
   println(ans)  //->  6
}t

```
関数化できた。これだけ・・・・

さらに、引数の型も**「->」**を使って、変換することもできる


*少しわかりやすくするために、addition関数の引数の型をstringにしています*

```kotlin:sample.kt
fun addition(n: String) = n.toInt() + 1

fun main(){
    val ownFunction: (String) -> Int = ::addition //-> ここら辺
    val ans = ownFunction("5") //-> 文字列から数値に変換している
    println(ans)  //->  6
}

```

##高階関数

- 関数を引数、戻り値として扱うことができる関数
- リファクタリングで、「似たようなコードの繰り返し」を減らすことができる


```kotlin:sample_2.kt

fun EvenOrAdd(ints:List<Int>) : Boolean{
    for(i in ints){
        if(i % 2 == 0){
            return true
        }
    }
    return false
}


fun Multiplesof10(ints: List<Int>): Boolean{
    for(i in ints){
        if(i % 10 == 0){
            return true
        }
    }
    return false
}


fun main(){
    println(EvenOrAdd(listOf(3,7,6))) //-> 偶数はある？
    println(Multiplesof10(listOf(92, 22, 12))) //10の倍数はある？
}

```
このファイルでは、2つの関数をあることを確かめようとしています。

- 偶数はあるのか（EvenOrAdd関数）
- 10の倍数はあるのか（Multiplesof10）


しかし、2つの関数内には、同じようなコードが存在しており、**一箇所に分けたいと考えております**。

ここで、高階関数の出番です
先ほどの、関数のオブジェクト化も利用すると・・・・・

```kotlin:sample_2

//新しく作成。まずは、ここが呼び出される
fun BranchSource(ints: List<Int>, judgment: (Int) -> Boolean): Boolean{
    for(i in ints){
        if(judgment(i)){ // ここで、それぞれの関数に判断をしてもらう
            return true
        }
    }
    return false
}


fun EvenOrAdd(i: Int) : Boolean = i % 2 == 0


fun Multiplesof10(i: Int): Boolean = i % 10 == 0


fun main(){
    println(BranchSource(listOf(3,5,8), ::EvenOrAdd)) //-> 偶数はある？
    println(BranchSource(listOf(92, 22, 12), ::Multiplesof10)) //10の倍数はある？
}


```

これによって、EvenOrAdd、Multiplesof10関数がはっきりと離れる形となったおかげで、

- コードがわかりやすく
- 関数の役割も見やすく
- 次に関数を利用したいときに、利用がしやすくなる。

などの利点が出てくる




##関数リテラル

関数リテラルとは、変数内に、**関数をデータの一種として扱うことができる**

- リテラルとは、変数の中に入る値のこと（数値や文字列）
- 先ほどの「関数のオブジェクト化」と同じ感じと捉えてよく、関数名がないのやり方である。
- 無名関数・匿名関数とも呼ばれる
- ラムダ式が有名

先ほどの「sample_2.kt」を参考にやってみたいと思います。

###ラムダ式で行う

```kotlin:sample_3.kt

fun BranchSource(ints: List<Int>, judgment: (Int) -> Boolean): Boolean{
    for(i in ints){
        if(judgment(i)){
            return true
        }
    }
    return false
}


fun main(){
    println(BranchSource(listOf(3,5,8), {it % 2 == 0})) //-> 偶数はある？
    println(BranchSource(listOf(92, 22, 12), {it % 10 == 0}))//10の倍数はある？
}


```

または、


```kotlin:sample_3.kt

fun BranchSource(ints: List<Int>, judgment: (Int) -> Boolean): Boolean{
    for(i in ints){
        if(judgment(i)){
            return true
        }
    }
    return false
}


fun main(){
    println(BranchSource(listOf(3,5,8)) {it % 2 == 0}) //-> 偶数はある？
    println(BranchSource(listOf(92, 22, 12)) {it % 10 == 0})//10の倍数はある？
 //関数の引数内からはみ出していてもOK
}


```


**it**とは、暗黙の変数である。

- 関数内の引数が単一である（一つしかない）場合は、itを使って、省略することができる。





###無名関数で行う

```kotlin:sample_4.kt

fun BranchSource(ints: List<Int>, judgment: (Int) -> Boolean): Boolean{
    for(i in ints){
        if(judgment(i)){
            return true
        }
    }
    return false
}


fun main(){
    println(BranchSource(listOf(3,5,8), fun(n: Int): Boolean = n % 2 == 0)) //-> 偶数はある？
    println(BranchSource(listOf(92, 22, 12), fun(n: Int): Boolean = n % 10 == 0))//10の倍数はある？
}


```

EvenOrAdd、Multiplesof10関数で書かれた式を、そのまま引数に書いてしまう方法です。

このままだと、長くて、わかりづらいので、省略をしていきます


```kotlin:sample_4.kt

fun BranchSource(ints: List<Int>, judgment: (Int) -> Boolean): Boolean{
    for(i in ints){
        if(judgment(i)){
            return true
        }
    }
    return false
}


fun main(){
    println(BranchSource(listOf(3,5,8), fun(n) = n % 2 == 0)) //-> 偶数はある？
    println(BranchSource(listOf(92, 22, 12), fun(n)= n % 10 == 0))//10の倍数はある？
}


```

無名関数の引数の型と返り値の型を省略できます。
~~短くはなったけど、引数の型が見えないから余計にわかりづらくなっている気が~~



##感想
まだ、これらを使う場面をイメージすることはできないが、何処かで使っているから、
参考書やチュートリアルで扱っているのだろうと思うので、挫けずに基本を学んでいきたい


##参考URL

- https://code-graffiti.com/functions-literal-in-javascript/
- https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/lambdas.html