kotlinの文法まとめ

自分用メモです。

# 文字列への変数展開
```
val name = "foge"
val str = "I am ${name}"
val expr = "1 + 2 = ${1+2}"
```

# when
値比較バージョン
```
when(value) {
    1 -> {
        println("one")
    }
    2, 3 -> {
        println("2 or 3")
    }
}
```
式バージョン
```
// 式
when {
    v == 0 -> {
       println("zero")
    }
    1 <= v && v <= 3 -> {
       println("1 - 3")
    }
}
```

# ifとwhenの代入式
```
val result1 = when(v) {
    1 -> "one"
    else -> "other"
}
val result2 = if (value2 == 1) 100 else 200 
```

# Pair型、Triple型
```
val p = Pair(1, "1")
val t = Triple(1, "1", 1.0)
```

# dataクラス

```
data class Person(val name: String, val age: Int)
val taro = Person("太郎", 100)
```

# enumクラス
```
enum class Color(val value: Int) {
    RED(0xff0000),
    BLUE(0x00ff00),
    GREEN(0x0000ff),
}
```

# sealedクラス
```
seald class Color {
    object Red: Color()
    object Blue: Color()
    data class HSL
}
```

# コレクションの初期化

```
// 配列の初期化
val array = arrayOf(1, 2, 3)

// リスト型の初期化
val list = listOf(1, 2, 3)

// マップ型
val m = mapOf("key" to "value")

// mapOf → mutalbeMapOf
val mm = m.toMutableMap()

// 可変リスト
val mlist = mutableListOf(1, 2, 3)

// シーケンス型
val seq = list.asSequence()

// 配列 → リスト (スプレッド演算子)
val list2 = listOf(*array)

// リスト → 配列
val array2 = list.toTypedArray()

// 範囲 → リスト
val list3 = (1..3).map{ v -> v }
val list4 = (1..3).toList()

```

# コレクション関数

```
// リスト型
val total1 = (1..100).toList().filter{ v -> v % 2 == 0}.map{ v -> v * 2}.reduce{ sum, value -> sum + value}
// シーケンス型
val total2 = (1..100).asSequence().filter{ v -> v % 2 == 0}.map{ v -> v * 2}.reduce{ sum, value -> sum + value}

// 伏字付きforeach
(1..100).toList().forEachIndexed { index, v -> println("${index}: ${v}") }

// スライス
val list = listOf(1, 2, 3, 4, 5)
println(list.slice(2..4))
println(list.slice(listOf(0, 1, 2)))

// ソート
var intArray = arrayOf(1, 2, 3)
intArray.sort()
intArray.sortWith(Comparator { i1, i2 -> i1 < i2})

// 要素チェック

intArray.any() // 1つ以上要素がある場合はtrue

```

# ループのBreak
```
run @loop {
    array.forEach { id -> 
        ・・・
        return@loop
        ・・・
}
```

# エルビス演算子
```
// getValue()がnullを返却した場合は例外をスロー
val value: Int? = getValue() ?: throw Exception()

// 関数リターン
val value: Int? = getValue() ?: return

// 別値を返却
val value2 = getValue() ?: 100
```

# 単一式の関数
```
fun power(val value: Float): Float  = value * value
```

# キャスト
```
// キャスト失敗時は例外スロー
val casted = value as Int

// キャスト失敗時はnull
val casted2 = value as? Int
```

# 型拡張
```
fun MutableList<Int>.sum(): Int = this.reduce{ sum, value -> sum + value }
val list = mutableListOf(1, 2, 3)
println(list.sum())
```

# プロパティ
```
// 読み取り専用
val hello: String
    get() = "Hello"

// 読み取り書込み可 (別のFieldに橋渡し)
var _hoge: String
var foge: String
    get() = _hoge
    set(value) {
        _hoge = value
    }

// 読み取り書込み可 (Field省略)
var foo: Int = 0
    get() = field
    set(value) {
        field = value
    }

```

# 初期化遅延
```
// 変数が参照される前に誰かが初期化する必要がある
lateinit var value1: MyClass

// 変数が参照されたときに自動で初期化する
var value2 by lazy {
    MyClass()
}

```

# 中間記法
```
data class Person(
    val id: Int,
    val name: String
)

data class PersonWithMeta(
    val id: Int,
    val name: String,
    val meta: String
)

infix fun Person.toWithMeta(meta: String) = PersonWithMeta(id, name, meta)

fun main() {
    val person = Person(10, "太郎")
    print(person toWithMeta "hoge")
}
```

# オペレータ関数のアップグレード
```
operator fun String.get(range: IntRange) = substring(range)
print("hogehoge"[0..3])
```

# 可変引数
```
fun printAll(vararg messages: String) {
    messages.forEach{ message -> println(message)}
}
printAll("aa", "bb", "cc")
```

# Generic
```
// クラスのジェネリック
class MyClass<E> (val value: E) {
  fun hello() {
      println("${value}")
  }    
}

// 関数のジェネリック
fun <E> hello(value: E) {
    println("${value}")
}
```

# 内部関数
```
fun main() {
    func innerFunc() {
    }

    innerFunc()
}
```

# ラムダ式
```
fun sum(a: Int, b: Int) = a + b
```

# クラス
```
class MyClass(val value: Int) {
}

class ExtendMyClass(value: Int): MyClass(value) {
}

class SomeConstructorClass: MyClass {
    constructor(): super(1) {}
    constructor(value: Int): super(value) {}
}

// コンストラクタのprivate宣言
class PrivateClass private constructor() {
}

```

# 別名インポート
```
import jp.co.com.MyClass as RenamedClass
```