これが Kotlin の文法か! と感じた場面

#はじめに
Kotlinを勉強し始めて１ヶ月ほど経過しました。
Kotlinも他の言語と共通する文法もあり、他の言語を知っていれば1から文法を勉強しなくてもなんとなく読めます。
そんな中でも僕が感じたKotlin特有というかKotlinぽい？というか、そんな記述をまとめてみました。
Kotlinを勉強し始める方は、勉強する前に前にさらっと目を通していただいて雰囲気をつかんでいただけますと幸いです。

#型の後置修飾
```kotlin 
var i : Int
val d : Double
val s : String
fun Area(height : Int, width : Int) : Int {return height * width}
```
　このように整数や浮動小数点、文字列などの変数の方を後置修飾します。また関数の返り値の型も関数名（引数）の後ろに置きます。
　変数には大きく分けてvar変数とval変数があります。val変数は再代入不可、var変数は再代入可です。ごっちゃになりやすいですね。。。基本的には再代入不可のval変数でコードを書いた方がバグの混入が減らせそうです。

#`if`
　Kotlinのifは文ではなく式です。なのでifを用いて以下のような記述ができます。

```kotlin
fun checkOddNumber(value: Int): Boolean{
    val res: Boolean = if(value % 2 == 0) true else false 
    return res
}
```
　式なので、これを展開して直接returnすることができます。Kotlinには三項演算子はなく、このようにif式を代替します。

```kotlin
fun checkOddNumber(value: Int): Boolean{
    return if(value % 2 == 0) true else false 
}
```
　もちろん文っぽくifを用いることもできます。

```kotlin
fun checkOddNumber(value: Int): Boolean{
    if(value % 2 == 0) {
        res = true
    } else {
        res = false
    }
    return res
}
```
#`when`
　CやJavaのswitch-case文のような機能です。こちらも式として変数に代入できますし、文として書くこともできます。

```kotlin
val kisetu: String = "夏"
val season: String
season = when(kisetu){
    "春" -> "Spring"
    "夏" -> "Summer"
    "秋" -> "Fall"
    "冬" -> "Winter"
    else -> "Unknown"
}
println(season)
//Summer
```
```kotlin
val kisetu: String= "冬"
when(kisetu){
    "春" -> {println("Spring")}
    "夏" -> {println("Summer")}
    "秋" -> {println("Fall")}
    "冬" -> {println("Winter")}
    else -> {println("Unknown")}
}
//Winter
```

#null安全
　Javaではnullの変数に対するメンバ変数/関数にアクセスしようとするとNullPointerExceptionが発生します。Kotlinでは基本的にnullを許容しないので、未然にNullPointerExceptionを防ぐことができます。コンパイル時にnullの変数が存在すればコンパイルエラーとなります。

```kotlin

var str : String
str = null
//error: null can not be a value of a non-null type String
```
　初期化されていない変数や変数のメソッドやメンバへのアクセスもコンパイルエラーとなります。

```kotlin
val members : Members
members.findByName("Bob")
...
class Members{
   ...
   fun findByName(...){...}
}
//error: variable 'members' must be initialized
```
　通常、変数は宣言時に初期化します。

```kotlin
val str: String = "Hello world"
println(str)
//OK
```
　一方、nullを許容する変数も存在します。`型名？`でnull許容型変数となります。null許容型変数をnullで初期化していれば、`error variable 'xxx' must be initialized`のエラーは出ません。以下のコードはコンパイルは正常に終了します。

```kotlin
var str: String?
str = null
//OK
```
　以下のコードで変数のメソッドやメンバを呼ぶ前にnullチェックを行ってくれます。もしnullなら無条件に`"null"`の文字列を返します。

```kotlin
var str: String?
str = null
println(str?.length) //"null"
//OK
```
　nullと未初期化状態は区別されます。そのため、null許容型と言っても以下のコードはエラーとなります。

```kotlin
var str: String?
println(str?.length) 
//error: variable 'str' must be initialized
```

　コンパイラがちょっと厳しいなあと感じることが多々あります。そのぶん出来上がりのコードの安全性はそれなりのものになってると信じたい！

#配列、リスト、マップ
　配列、リスト、マップの宣言の仕方は以下の通りです。
　初期化を行うには`xxxOf（）`を用います。こちらは読み取りのみできる配列、リスト、マップです。マップに関しては`key to value`の記述で、マップのkeyとvalueを登録します。読み取りのみのものは最初の初期化は値を追加したり、削除することはできません。`MutableXxx`, `mutableXxxOf`で読み書きができる配列、リスト、マップの宣言と初期化を行うことができます。

```kotlin
//読み取りのみ
var array : Array<String> = arrayOf("春", "夏", "秋", "冬")
var list : List<String> = listOf("春", "夏", "秋", "冬") 
var map : Map<String, String> = mapOf("春" to "Spring", "夏" to "Summer")
//要素の追加削除変更ができる
var mutalearray : MutableArray<String> = mutableArrayOf(...)
var mutablelist : MutableList<String> = mutableArrayOf(...)
var mutablemap : MutableMap<String, Int> = mutableArrayOf(...)
```
　(コメントから追記)`key to value`に関して、これは言語で定められた構文ではなく、Pair クラスのインスタンスを生成する [`to` 関数](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/to.html) の呼び出しです。 Kotlin では二項演算子のように使える中置関数を定義することができます。
　例えば以下のように宣言しておいて、リストに値を追加しようとしてもコンパイルエラーとなります。

```kotlin
var season : MutableList<String>
season.add("春")
//variable 'season' must be initialized
```
`season`には初期化しない限りnullだからです。初期値は入れないけど、後で値を入れる想定なら、`mutableListOf`で空のリストで初期化します。

```kotlin
var season : MutableList<String> = mutableListOf()
season.add("春")
```

#`for`と`forEach`
kotlinではforで指定数の繰り返し処理や、配列やリスト、マップの各要素に任意の処理をすることができます。

```kotlin
val season : Map<String, String> = mapOf("春" to "Spring", "夏" to "Summer", "秋" to "Fall", "冬" to "Winter")
for (elem in season){
    println("${elem.key} ${elem.value}")
}
var sum : Int = 0
for (i in 1..10){
  sum += i
}
//iを２ずつ加算してループを実行
var odd_sum : Int = 0
for (i in 1..10 step 2){
  odd_sum += i
}
```
forEachは配列やリスト、マップのメソッドで、ほぼforと同じことができます。

```kotlin
val season : Map<String, String> = mapOf("春" to "Spring", "夏" to "Summer", "秋" to "Fall", "冬" to "Winter")
season.forEach({
  elem -> println("${it.key} ${it.value}")
})
```
　forEachでは各要素に対して処理したい内容の関数を引数にとります。このように引数に関数をとる関数を高階関数と呼びます。また引数の関数はラムダ式で記述されることが多いです。
#型推論
Kotlinでは変数の型を明示しなくても、初期化する値によって型を自動で定義してくれます。

```kotlin
val num1 = 10 //Int
val num2 = 9.8 //Double
val str = "Hello" //String
val season = mapOf("春" to "Spring", "夏" to "Summer", "秋" to "Fall", "冬" to "Winter") //Map<String, String>
```
静的型付けの恩恵を受けつつ、コードもすっきりします。
#ラムダ式と高階関数
　試しに引数で当てられた関数の実行時間を計測する高階関数（measureTime）を作ってみます。

```kotlin
//UnitはC言語でいうvoid型みたいなもの
fun measureTime(targetFunction: (Int) -> Unit) : Long{
    val start = System.currentTimeMillis()
    targetFunction(1000000)
    val end = System.currentTimeMillis()
    return end - start
}
```
`fun measureTime(targetFunction: (Int) -> Unit) : Long`
この部分、関数引数の指定の仕方は、`関数名 : (引数, ...) -> 返り値の型`です。
計測する関数は以下の関数とします。

```kotlin
fun target(loop){
   var x = 0
   for(i in 1..loop) {x++}
}
```
この関数を引数に入れます。
関数へは`::`を付けることで参照できます。

```kotlin
var time : Int = measureTime(::target)
println(time)
//3(ex)
```
この`target`関数はラムダ式（無名関数）で記述できます。

```kotlin
var time : Long = measureTime({loop : Int -> 
    var x = 0
    for(i in 1..loop) {x++}
})
println(time)
//3(ex)
```

`{引数,... -> 処理内容}` でラムダ式を記述します。関数の最後の引数がラムダ式の場合、ラムダ式は関数の()の外に出せます。この例では引数がラムダ式のみなので、ラムダ式が最初の引数であって最後の引数です。()には残りの変数の引数が入り得ます。

```kotlin
var time : Long = measureTime(){loop : Int -> 
    var x = 0
    for(i in 1..loop) {x++}
}
```

また関数の引数がラムダ式だけの場合、関数の（）も省略できます。結局引数がラムダ式１つだけの場合は以下のように（）を省略できます。

```kotlin
var time : Long = measureTime{loop : Int -> 
    var x = 0
    for(i in 1..loop) {x++}
}
```
同様にしてforEachも（）を省略できます。

```kotlin
season.forEach{ elem ->
  println("${elem.key} ${elem.value}")
}
```
　（コメントを受けて）暗黙的に仮引数が1つしかないラムダ式の引数は`it`として定義されます。forEachでは各要素は変数`it`に入れられ、以下のように書けます。

```kotlin
season.forEach{
  println("${it.key} ${it.value}")
}
```
すっきりしましたね！

#最後に
Kotlinの特徴的な文法などをまとめてみました。
今回は基礎部分だけだったのでこれの続編もそのうち書こうと思います。
コメントくださった方ありがとうございます！



#参考文献
`速習Kotlin（Kindle） 著：山田祥寛`