Kotlin自己学習 基本的な文法


[Kotlinスタートブック](http://amzn.asia/4bR2K7c)（赤べこ本）を読んで学習した結果をアウトプットする。

## データ型

```kotlin
    //Double
    val d: Double = 123.4
    //Float
    val f: Float = 1234.5f
    //Long
    val l: Long = 1234L
    //Int
    val i: Int = 12345
    //Short
    val s: Short = 1234
    //Byte
    val b: Byte = 0x0F
    //Boolean
    val bl: Boolean = true
    //Char
    val c: Char = 'c'
    //String
    val str: String = "String"

    //演算
    //Javaと同じ
    println(1 + 2) //=>3
    println(1 + 2 * 3) //=>7
    println(2.5 + 1) //=>3.5
    //比較演算子
    println(1 < 2) //=>true
    println(5 == 0) //=>false

    //型推論
    val name1: String = "Taro"
    //name1はStringになると推論できるので型を省略できる
    val name2 = "Taro"
```

### 文字列

```kotlin
    //文字列
    val name = "kotlin"
    //頭文字を参照
    println(name[0]) // => K
    // 文字列の長さ
    println(name.length) // => 6
    //頭文字を大文字
    println(name.capitalize()) // => Kotlin
    //空文字、空白だとtrueを返す
    println(name.isBlank()) // => false

    //文字列結合
    println("Hello " + name + "!") // => Hello kotlin!
    //Stringテンプレート
    println("Hello $name!") // => Hello kotlin!
    // raw string
    println("""
Hello $name!
""")
    // =>
    // => Hello kotlin!
    // =>

    //行頭に|で目印にできるが、trimMarginをを忘れずに！
    println("""
    |Hello
    |$name
    |!
    """.trimMargin())
    // => Hello
    // => kotlin
    // => !

```

## 変数
変数(variable)は下記の書式で記述する
`val 変数名: 型 = 式`

val 再代入不可、原則こちらを使う
var 再代入可能


## 配列

```kotlin
    val ints = arrayOfNulls<Int>(5)
    println(ints.size) // => 5
    println(ints[0]) // => null
    ints[0] = 123
    println(ints[0]) // => 123
    val ints2: IntArray = intArrayOf(1, 2, 3)
    println(ints2[0]) // => 1

```
## List

不変/可変で使い分ける必要がある

```kotlin
    //ミュータブルなリストはMutableListインタフェース
    val chars: MutableList<Char> = mutableListOf('a', 'b')
    println(chars) // => [a, b]
    //更新
    chars[0] = 'c'
    println(chars) // => [c, b]
    //追加
    chars += 'x'
    println(chars) // => [c, b, x]
    //削除
    chars -= 'x'
    println(chars) // => [c, b]
    chars.removeAt(0)
    println(chars) // => [b]
```

## Set

不変/可変で使い分ける必要がある

```kotlin
    // イミュータブル
    val ints: Set<Int> = setOf(1, 2, 1, 3)
    println(ints) //=> [1, 2, 3]
    // ミュータブル
    val chars: MutableSet<Char> = mutableSetOf('a', 'a', 'b')
    println(chars) //=>[a, b]
    // 削除
    chars -= 'a'
    println(chars) //=>[b]
```

## Map

不変/可変で使い分ける必要がある

```kotlin
    //イミュータブル
    val numberMap: MutableMap<String, Int> = mutableMapOf("one" to 1, "tow" to 2)
    println(numberMap) //=> {one=1, tow=2}
    //サイズ
    println(numberMap.size) //=> 2
    //Keyを指定してValueを取得
    println(numberMap["one"]) //=> 1
    //存在しないKeyを指定
    println(numberMap["three"]) //=> null
    //追加はPairを足す
    numberMap += "three" to 3
    println(numberMap) //=> {one=1, tow=2, three=3}
```

## Range

範囲を表すオブジェクト
例えば1から10までの範囲を表すには`1..10`と記述する

```kotlin
    //5は1〜10に含まれているか？
    println(5 in 1..10) //=> true
    
    //inを使うとレンジオブジェクトの範囲内かをテストできる
    val range: IntRange = 12..15
    println(5 in range) //=> false

    // !inは否定
    println(5 !in range) //=> true

    //toListでリストオブジェクトに変換できる
    println((1..5).toList()) //=> [1, 2, 3, 4, 5]

    //reversedで逆レンジ
    println((1..5).reversed().toList()) //=> [5, 4, 3, 2, 1]
    //もっと簡潔にするには downTo
    println((5 downTo 1).toList()) //=> [5, 4, 3, 2, 1]
    //stepで増減の間隔を調整できる
    println((1..5 step 2).toList()) //=> [1, 3, 5]
    println((100 downTo 0 step 25).toList()) //=> [100, 75, 50, 25, 0]
```

## 条件分岐

### if

```kotlin
    var score = 50
    if (score >= 60) {
        println("合格")
    } else {
        println("不合格")
    }
    //=> 不合格

    //上の式はこう書く事もできる
    val messsage = if (score >= 60) "合格" else "不合格"
    println(messsage) //=> 不合格

    // 5は1〜10の中に含まれるか？
    if (5 in 1..10) {
        println("wawa") //=> wawa
    }

    //ブロックを取る場合はそのブロック内で最後に評価される式が返される
    val x = if (true) {
        1
        2
    } else {
        3
    }
    println(x) //=> 2

    // 条件分岐のチェーンを形成することもできる
    score = 75
    val grade =
            if (score >= 90) 'A'
            else if (score >= 80) 'B'
            else if (score >= 70) 'C'
            else if (score >= 60) 'D'
            else 'F'
    println(grade) //=> C
```

### when

when式はJavaにおけるswitchを協力にしたようなもの

```kotlin
    //単純な使い方
    val x = 1
    var message = when (x) {
        1 -> "one"
        2, 3 -> "two or three"
        else -> {
            "unknown"
        }
    }
    println(message) //=> one

    //様々な条件で分岐が可能
    val y = 20
    message = when (y) {
        1 -> "one"
        myFavoriteInt() -> "favorite: $y"
        in 2..10 -> "1 <= x <= 10"
        else -> y.toString()
    }
    println(message) //=> favorite: 20

    //isを用いて型チェックで分岐
    val str = "hello"
    val blank = when (str) {
        is String -> str.isBlank()
        else -> true
    }
    println(blank) //=> false

    //ifのチェーンに置き換えると見やすい
    val score = 50
    when {
        score >= 90 -> 'A'
        score >= 80 -> 'B'
        score >= 70 -> 'C'
        score >= 60 -> 'D'
        else        -> 'F'
    }
    
fun myFavoriteInt(): Any {
    return 20
}
```

## ループ

### while

```kotlin
    var count = 3
    while (count-- > 0) {
        println("Hello")
    }
    //->Hello
    //->Hello
    //->Hello

```

### do-while


```kotlin
    do {
        println("Hello")
        val next = Math.random() < 0.5  //変数nextをwhileの条件に指定できる
    } while (next)

    //->Hello
    //...
```

### for

一般的な書式

for (要素名 in イテレータを提供するオブジェクト) {
　　ループしたい処理内容
}



```kotlin
    for (x in arrayOf(1, 2, 3)) {
        println(x)
    }
    //-> 1
    //-> 2
    //-> 3

    val names = listOf("foo", "bar", "baz")
    for (name in names) {
        println(name)
    }
    //-> foo
    //-> bar
    //-> baz

    for (i in 1..10 step 2) {
        println(i)
    }
    //-> 1
    //-> 3
    //-> 5
    //-> 7
    //-> 9
```

### break

```kotlin
    var barIndex = -1
    //barが最初に登場するインデックスを取得する
    for (index in names.indices) {
        println(index) //-> 0,1,2などのインデックス
        if (names[index] == "bar") {
            barIndex = index
            break   //barが見つかったらループを抜ける
        }
    }
    println(barIndex) //-> 1

    //ラベル付きのジャンプ
    loop@ for (x in 1..10) {
        for (y in 1..10) {
            if (y == 5) {
                break@loop
            }
        }
    }
```

※indicesはリストや配列に定義されているプロパティで、全要素分のインデックスをレンジとして返す