View on GitHub

Today I Learned

Software Engineering Blog

Kotlin Grammer

Introduction

Function

voidのように返り値でなにも返さない場合はUnit。 省略可能

関数の引数にデフォルト値を指定できる

標準ライブラリにPair型がある

val pair = "A" to "B"
println(pair)    // (A, B)

varargで引数を可変長にできる

fun printAll(vararg messages: String) {
    for (m in messages) println(m)
}
printAll("Hello", "Hallo", "Salut", "Hola", "你好")

variable

valで変数を定義。immutable。基本的にはこれを使う。varは変更する場合のみ

Null Safety

可能な限りNullPointerExceptionを排除するために、Kotlinはいくつかの型でnullを許可しない。

変数をnullにしたい場合は、普通の型に?をつけることで、NPEを発生しにくくする

var neverNull = "This can't be null"
//neverNull = null

var nullable: String? = "You can keep a null here"
nullable = null

var inferredNonNull = "The compiler assumes non-null"
//inferredNonNull = null

fun strLength(notNull: String): Int {
    return notNull.length
}
println(neverNull)
println(nullable)

?: エルビス演算子。三項演算子 A ? B : C のBが内容な機能。これでnullの場合の処理を書くことができる

printString(todo.text ?: "")   //  todo.textがnullの場合にから文字を出力

Classes

コンストラクタを定義しないと自動で引数なしコンストラクタが生成される

1つのプライマリコンストラクタと複数のセカンダリコンストラクタが使える

インスタンス生成にnewは不要

Control Flow

When

switch文の代替。is Long でタイプ一致、else はbreak。

fun cases(obj: Any) {
    when (obj) {
        1 -> println("One")
        "Hello" -> println("Greeting")
        is Long -> println("Long")
        !is String -> println("Not a string")
        else -> println("Unknown")
    }
}

fun main() {
    // Greeting
    cases("Hello")
    // One
    cases(1)
    // Long
    cases(0L)
    // Unknown
    cases("hello")
} 

型チェックにis!isが使える。チェックした後自動的にキャストされる

if文では値を返すこともできる

Equality Checks

==は順番無視で値が同じ(equalsメソッドによる同一性チェック)ならtrue, ===は参照が同じならtrue

val authors = setOf("Shakespeare", "Hemingway", "Twain")
val writers = setOf("Twain", "Shakespeare", "Hemingway")

// true
println(authors == writers)
// false
println(authors === writers)

Special Classes

Data Classes

すべてのクラスはAnyを継承する

データクラスは、データを保持したいだけのクラスとして使われる。class宣言の最初にdataをつける。setter, getterの宣言は不要

Object Keyword

companion object はJavaの static finalと同じ

Collections

List

Listは中身の変更が不可、mutableListは変更可能。同様にmutableMapもある。

MutableListからListにアップキャストできる

Listの初期化

var myList: ArrayList<Int> = arrayListOf()

any, all, none

anyは、Collectionの少なくとも一つの要素が条件を満たしていればtrueを返す

val numbers = listOf(1, -2, 3, -4, 5, -6)
val anyNegative = numbers.any { it < 0 }
val anyGT6 = numbers.any { it > 6 }
// true
println(anyNegative)
// false
println(anyGT6)

allは、Collectionの全ての要素が条件を満たしていればtrueを返す

val numbers = listOf(1, -2, 3, -4, 5, -6)
val allEven = numbers.all { it % 2 == 0 }
val allLess6 = numbers.all { it < 6 }
// false
println(allEven)
// true
println(allLess6)

noneは、Collectionの全ての要素が条件を満たしていなければtrueを返す

val numbers3 = listOf(1, -2, 3, -4, 5, -6)
val noneEven = numbers3.none { it % 2 == 1 }
val noneLess6 = numbers3.none { it > 6 }
// false
println(noneEven)
// true
println(noneLess6)

ScopeFunctions

let

letはnullチェックに使われる引数として関数を受け取り、元の関数がnullの場合はnullを返す。JavaのOptionalに似ている。

val empty = "test".let {
    it.isEmpty()
}
println(" is empty: $empty")

fun printNonNull(str: String?) {
    println("Printing \"$str\":")

    str?.let {
        print("\t")
        println()
    }
}
printNonNull(null)
printNonNull("my string")

関数はパッケージのトップレベルで宣言できるのでクラスメソッドにする必要はない

useはJavaのtry-with-resources

buildStringはJavaのStringBuilder