Java開発者に送るKotlinこと始め

私がKotlinでの開発を始めた頃、戸惑ったポイントを書きます。
この記事を読んだJava開発者の方が、Kotlin開発のいいスタートが切れますように...

#変数宣言
Javaで変数を宣言してみます。

```java
int i = 0;
```

これをKotlinで書くと

```kotlin
var i: Int = 0
```

こうなります。

* セミコロン不要 (あっても良いです)
* 型を記述する位置が違う→`変数名`:`型`

では、`var`は？

## varとval
`var` (variable)
Javaのfinalじゃない変数と同じです。初期化後に再代入できます。

`val` (value)
Javaのfinal付き変数と同じです。初期化後に再代入できません。

```kotlin
    val i: Int = 0
    i = 1 // コンパイルエラー

    var i: Int = 0
    i = 1 // OK
```

**変数はなるべく、再代入NGの`val`で宣言しましょう。
`var`は必要な時だけにしましょう。**

ちなみに`val`の場合でも、宣言箇所で初期化しなくても良いです。

```kotlin
    val i: Int
    if (flag) {
        i = 1
    }
    else {
        i = 4
    }
```

## 型推論
Kotlinには型推論があります。

推論を使わずに変数を宣言すると、↓ですが

```kotlin
    val i: Int = 0
```

推論を使うと型を省略できます↓

```kotlin
    val i = 0
```

リテラルから型を推論してみます。

```kotlin
val i = 0 // Int
val l = 0L // Long
val f = 0F // Float
val d = 0.0 // Double
val c = 'c' // Char
val str = "str" // String
```

関数の戻り値を推論してみます。

```kotlin
fun getString(): String {
    return "kotlin"
}
val str = getString()
// val str: String と書かなくても良い
```

# `switch`がない
Kotlinに`switch`がありません。代わりに`when`があります。

曜日を表すenumを扱ってみます。

```kotlin
    enum class DayOfWeek {
        SUN, MON, TUE, WED, THU, FRI, SAT
    }

    val dayOfWeek: DayOfWeek = DayOfWeek.MON
    // 土日は良いです それ以外は悪いです
    when (dayOfWeek) {
        DayOfWeek.SUN -> println("Good!")
        DayOfWeek.SAT -> println("Good!")
        else -> println("Bad...")
    }
```

式が2つ以上の場合は`->`に続けて`{` `}` で囲う事もできます。

```
when { 
    `条件` -> { `式` }
}
```

whenでbreak句は使えません。デフォルトでbreakします。
複数条件を一括で扱いたい場合は、カンマで区切ります。

```kotlin
    when (dayOfWeek) {
        DayOfWeek.SUN, DayOfWeek.SAT -> println("Good!")
        else -> println("Bad...")
    }
```


# `if`や`when`や`try`が文じゃなくて式
`if`、`when`、`try`は式なので結果を変数に代入したり、関数の戻り値として扱うことができます。

```kotlin
    val v = if (flag) {
        "I like Kotlin!"
    } else {
        "(T_T)"
    }
```

最後に評価された式が、ifの結果となります。
`flag`がtrueだった場合、`"I like Kotlin!"`がif式の結果となり、
変数`v`に代入されます。

上の例は、ちょうどJavaの三項演算子と同じ用法です。
kotlinに三項演算子はありません。

```java
// Java
String v = flag ? "I like Kotlin!" : "(T_T)";
```

# `void`がない
Kotlinに`void`はありません。
戻り値のない関数を表す場合は`Unit`という型を使います。

```kotlin
fun doSomething(): Unit {
  // doSomething
}
```

# コレクション
ListやArrayのインスタンスを生成する便利な関数があります。


```kotlin
    val list = listOf(0, 1, 2)
    val empty = emptyList<Int>()
    val arr = arrayOf('a', 'b', 'c')
    val empty = emptyArray<Char>()
```

`XXXof()`は可変長引数の関数で、コレクションの要素を記述できます。
空のコレクションを生成する場合は`emptyXXX()`関数が便利です。

|型|生成|空生成|
|:--|:--|:--|
|Array|arrayOf()|emptyArray()|
|List|listOf()|emptyList()|
|Set|setOf()|emptySet()|
|Map|mapOf()|emptyMap()|

要素の方が推論できない場合は、型パラメータを指定する必要があります。

```kotlin
val numList = listOf<Number>(0.0F, 100, 1_000_000_000_000L)
```

## Mutableなコレクション
Kotlinのコレクションは大きく分けて2種類あります。
変更可能なコレクション(Mutable)と、変更不可なコレクション(Immutable)です。
要素を追加する`add()`関数や、削除する`remove()`関数はMutableなコレクションにしか存在しません。

|Immutable|Mutable|
|:--|:--|
|List|MutalbeList|
|Set|MutableSet|
|Map|MutableMap|

Mutableなコレクションを生成するには`mutableXXXof()`関数が便利です。

```kotlin
    val list = mutableListOf(0, 1, 2)
    list.add(3)
```

# 関数と変数はクラスに属さなくても良い

Javaと違い、Kotlinの関数と変数はクラスに属さなくてもOKです。

```kotlin
import com.package

// クラスに属さない関数
fun topLevelFunction() {
    // do something
}

// クラスに属さない変数
var topLevelVariable = 0

class Hoge {

}
```