たのしいKotlin1.1ツアー

  • 19
    いいね
  • 0
    コメント

Kotlin1.1の新機能のサマリです。
目玉FeatureっぽさがあるCoroutinesとType aliasesはここでは省略します。
元ネタはWhat's New in Kotlin 1.1

Coroutines

省略

Type aliases

省略

Bound callable references

1.0までは関数や引数自身のメソッドを関数参照として使用出来ましたが、1.1からは他の変数のメソッドを関数参照として使用できるようになりました。

val numbers = listOf("abc", "123", "456")
// 1.0でも出来たこと
// 関数参照
fun isAbc(str: String) = str.equals("abc", true)
numbers.filter(::isAbc)
numbers.map(String::toUpperCase)

// 1.1で出来るようになったこと
// 他の変数の関数参照
val numberRegex = "\\d+".toRegex()
numbers.filter(numberRegex::matches)

// ※これはもちろん1.0でも出来た
numbers.filter { numberRegex.matches(it) }

Sealed and data classes

SealedクラスのサブクラスをSealedクラスのインナークラスとしてだけではなく、同一ファイル内に並列に定義することも出来るようになりました。
また、dataクラスは今までは他のクラスを継承することが出来ませんでしたが、これも可能になりました。

sealed class Expr

// Exprのサブクラスを並列に宣言
class Const(val number: Double) : Expr()

// dataクラスは他のクラスを継承が可能に。sealedクラスのサブクラスにも出来ます。
data class Sum(val e1: Expr, val e2: Expr) : Expr()

Underscores for unused parameters

ラムダで使用しない引数をアンダースコアで明示する事が出来るようになりました。

map.forEach { _, value -> println("$value!") }

Destructuring Declarations

Destructuring Declarations(分解宣言)がラムダ式の引数でも使用出来るようになりました。
KotlinではPairやMapなどをval (a, b) = pairのように複数の変数として宣言する事が出来ますが、1.1ではラムダの引数を直接(a, b)のような分割した形で記述する事が出来るようになりました。

val map = mapOf(1 to "one", 2 to "two")
// 今までは引数を展開し直す必要があった ※entryはmapのkeyとvalueを持った型
map.map { entry ->
    val (key, value) = entry
    "$key -> $value!"
}

// 1.1では直接keyとvalueを引数として受ける事が可能に。
map.map { (key, value) -> "$key -> $value!" }

Underscores in numeric literals

KotlinでもJavaのように数値リテラルにアンダースコアを挟んで読みやすく出来るようになりました。

val oneMillion = 1_000_000
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010

Shorter syntax for properties

プロパティの型をgetterから推論して省略出来るようになりました。

data class Person(val name: String, val age: Int) {
    // 1.1で出来るようになったこと
    val isAdult get() = age >= 20 // Property type inferred to be 'Boolean'

    // 1.0までは型宣言が必要だった
    val isChild : Boolean get() = age < 20

    // これは1.0でも推論してくれた
    val isBaby = age < 5
}

Inline property accessors

プロパティのアクセサにもinlineが使用出来るようになりました。
プロパティ自体にinlineを付けて両アクセサにinlineを指定する事も出来ます。

public val <T> List<T>.lastIndex: Int
inline get() = this.size - 1

Local delegated properties

ローカル変数にもby lazyなどのdelegeted propertyが使用出来るようになりました。

val answer by lazy {
    println("Calculating the answer...")
    1 + 1
}
if (needAnswer()) {
    println("The answer is $answer.")   // answerはここで初めて計算される
} else {
    println("Sometimes no answer is the answer...") // この場合はanswerは計算されない
}

Generic enum value access

Enumをジェネリクスとして定義して扱えるようになりました。

enum class RGB { RED, GREEN, BLUE }

// Enumをジェネリクスとして受取り全ての値のnameを出力する関数
inline fun <reified T : Enum<T>> printAllValues() {
    print(enumValues<T>().joinToString { it.name })
}

fun printAllRGBColor() {
    printAllValues<RGB>()
}

他にもいろいろあるので詳しくはWhat's New in Kotlin 1.1