Kotlin 1.5の変更点

※ソース記事は[こちら](https://kotlinlang.org/docs/whatsnew15.html)
※Kotlin/JSやKotlin/Nativeについては個人的に使っていないので、割愛します。

Kotlin 1.5は新しい言語機能、安定した中間表現ベースのJVMコンパイラバックエンド、性能改善、実験的な機能の安定化や時代遅れの機能の非推奨化といった漸進的な変更を導入している。
変更の概要は[リリースブログ投稿](https://blog.jetbrains.com/kotlin/2021/04/kotlin-1-5-0-released/)にも記載されている。
# 言語の機能
Kotlin 1.5は[1.4.30でプレビュー](https://kotlinlang.org/docs/whatsnew1430.html#language-features)のために提示された新しい言語機能を安定板をもたらしている。
- JVMレコードのサポート
- sealedインターフェイスとsealedクラスの改善
- インラインクラス

これらの機能の詳細な説明は[こちらのブログ投稿](https://blog.jetbrains.com/kotlin/2021/02/new-language-features-preview-in-kotlin-1-4-30/)と、Kotlinドキュメントの対応するページで利用可能である。

## JVMレコードのサポート
Javaの進化は早く、Kotlinは相互運用を確実にし続けるため、その最新の機能、[レコードクラス](https://openjdk.java.net/jeps/395)のためのサポートを導入した。
JVMレコードのためのKotlinのサポートは、双方向からの相互運用性を含んでいる。
- Kotlinコードでは、プロパティを持つ典型的クラスを使うように、Javaのレコードクラスを使うことができる。
- JavaコードでKotlinクラスをレコードとして使うためには、`data`クラスとして、`@JvmRecord`アノテーションをつけること。
```Kotlin
@JvmRecord
data class User(val name: String, val age: Int)
```
[KotlinでJVMレコードを使うことについての知識を深める](https://kotlinlang.org/docs/jvm-records.html)
## sealedインターフェイス
Kotlinのインターフェイスは今は、`sealed`修飾子を使うことができ、クラスに作用するのと同じ方法で、インターフェイスに作用する。つまり、sealedインターフェイスを実装するすべてのクラスはコンパイル時に判明する。
```Kotlin
sealed interface Polygon
```
この事実にのっとり、例えば、網羅的な`when`句を書くことができる。
```Kotlin
fun draw(polygon: Polygon) = when (polygon) {
   is Rectangle -> // ...
   is Triangle -> // …
   // elseは不要。すべてのありうる実装はカバーされている。
}
```
さらに、クラスは直接一つ以上のselaedインターフェイスを実装することができるため、sealedインターフェイスは、制限されたクラス階層をよりフレキシブルにすることができる。
```Kotlin
class FilledRectangle: Polygon, Fillable
```
[sealedインターフェイスについての知識を深める](https://kotlinlang.org/docs/sealed-classes.html)
## パッケージレベルのsealedクラス階層
sealedクラスは、今は同じコンパイル単位と、同じパッケージのすべてのファイルで、サブクラスを持つことができる。以前はすべてのサブクラスは同じファイルに出現していなければならなかった。
直接のサブクラスは、トップレベルか、いくつもの他の名前付きクラス、名前付きインターフェイス、名前付きオブジェクトの中にネストすることができる。
sealedクラスのサブクラスは、適切に修飾された名前をもたなければならない。ローカルや名前の無いオブジェクトであってはならない。
[sealedクラス階層についての知識を深める](https://kotlinlang.org/docs/sealed-classes.html#location-of-direct-subclasses)
## インラインクラス
インラインクラスは、値を持つだけの[値ベースのクラス](https://github.com/Kotlin/KEEP/blob/master/notes/value-classes.md)である。これにより、メモリ割り当てからくる追加のオーバーヘッド無しで、ある型の値のためのラッパーを使うことができる。
インラインクラスはクラス名の前に、`value`修飾子を宣言しなければならない。
```Kotlin
value class Password(val s: String)
```
JVMバックグラウンドでは、特別な`@JvmInline`アノテーションも必要である。
```Kotlin
@JvmInline
value class Password(val s: String)
```
`inline`修飾子は今は警告つきの非推奨である。
[inlineクラスについての知識を深める](https://kotlinlang.org/docs/inline-classes.html)
# Kotlin/JVM
Kotlin/JVMは、内部的と、ユーザー向け両方の多くの改善を受け取っている。ここでは、その中からもっとも注目すべきものを挙げる。
- 安定したJVM中間表現のバックエンド
- 新しいデフォルトのJVMターゲット:1.8
- invokedynamic経由のSAMアダプタ
- invokedynamic経由のラムダ
- @&#xFFF0;JVMDefaultと古いXjvm-defaultモードの非推奨
- null許容可否アノテーションの扱いの改善
## 安定したJVM中間表現のバックエンド
Kotlin/JVMコンパイラのための[中間表現ベースのバックエンド](https://kotlinlang.org/docs/whatsnew14.html#new-jvm-ir-backend)は今は安定しており、デフォルトで有効である。
Kotlin 1.4.0から、中間表現ベースのバックエンドの初期バージョンはプレビューのため利用可能だったが、今では言語バージョン`1.5`のためデフォルトになった。
[こちらのブログ投稿](https://blog.jetbrains.com/kotlin/2021/02/the-jvm-backend-is-in-beta-let-s-make-it-stable-together/)の中で、中間表現バックグラウンドのメリットと、その将来の開発についての詳細を記載している。
もし、Kotlin 1.5.0で古いバックエンドを使う必要がある場合は、プロジェクト設定ファイルに以下の行を追加することができる。
- Gradle
```Kotlin
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> {
  kotlinOptions.useOldBackend = true
}
```
- Maven
```xml
<configuration>
    <args>
        <arg>-Xuse-old-backend</arg>
    </args>
</configuration>
```
## 新しいデフォルトのJVMターゲット:1.8
Kotlin/JVMコンパイラのデフォルトのターゲットバージョンは、今は1.8であり、1.6ターゲットは非推奨である。
もし、JVM1.6でビルドする必要がある場合は、このターゲットを切り替えることができる。方法を知るには以下を参照。
- [Gradle](https://kotlinlang.org/docs/gradle.html#attributes-specific-to-jvm)
- [Maven](https://kotlinlang.org/docs/maven.html#attributes-specific-to-jvm)
- [コマンドラインコンパイラ](https://kotlinlang.org/docs/compiler-reference.html#jvm-target-version)
## invokedynamic経由のSAMアダプタ
Kotlin 1.5.0は、SAM(単一の抽象メソッド)変換をコンパイルするために、今では次の範囲でinvokedynamicを使用する。
- SAMの型が[Javaインターフェイス](https://kotlinlang.org/docs/java-interop.html#sam-conversions)の場合は、任意の式
- SAMの型が[Kotlinの関数インターフェイス](https://kotlinlang.org/docs/fun-interfaces.html#sam-conversions)の場合は、ラムダ

新しい実装は、[`LambdaMetaFactory.metafactory()`](https://docs.oracle.com/javase/8/docs/api/java/lang/invoke/LambdaMetafactory.html#metafactory-java.lang.invoke.MethodHandles.Lookup-java.lang.String-java.lang.invoke.MethodType-java.lang.invoke.MethodType-java.lang.invoke.MethodHandle-java.lang.invoke.MethodType-)を使用し、コンパイル時に補助のラッパークラスを生成しない。これはアプリケーションのjarサイズを小さくし、JVMの起動性能を改善する。
無名クラスの生成に戻づく、古い実装の仕組みに戻すには、`-Xsam-conversions=class`コンパイラオプションを追加すること。
[Gradle](https://kotlinlang.org/docs/gradle.html#compiler-options)、[Maven](https://kotlinlang.org/docs/maven.html#specifying-compiler-options)、[コマンドラインコンパイラ](https://kotlinlang.org/docs/compiler-reference.html#compiler-options)で、コンパイラオプションを追加する方法を理解する。
## invokedynamic経由のラムダ
:::note warn
プレーンなKotlinのラムダをinvokedynamicにコンパイルするのは、[実験的](https://kotlinlang.org/docs/components-stability.html)である。それはどんな時も削除あるいは変更されるかもしれない。Opt-inが必要(詳細は以下を参照)で、評価目的のためにのみ使うべきである。[You Track](https://youtrack.jetbrains.com/issue/KT-45375)上でフィードバックを聞けることを感謝する。
:::

Kotlin 1.5.0では、プレーンなラムダ(関数インターフェイスのインスタンスに変換されないもの)をinvokedynamicにコンパイルするための実験的サポートを導入している。その実装は[`LambdaMetafactory.metafactory()`](https://docs.oracle.com/javase/8/docs/api/java/lang/invoke/LambdaMetafactory.html#metafactory-java.lang.invoke.MethodHandles.Lookup-java.lang.String-java.lang.invoke.MethodType-java.lang.invoke.MethodType-java.lang.invoke.MethodHandle-java.lang.invoke.MethodType-)を使用して軽いバイナリを生成し、実行時に必要なクラスを効果的に生成する。現時点では、通常のラムダのコンパイルに比べて３つの制限がある。
- invokedynamicにコンパイルされたラムダはシリアライズ可能ではない
- そのようなラムダへの`toString()`呼び出しは読みづらい文字列表現を生成する
- 実験的な[`reflect`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect.jvm/reflect.html)APIは、`LambdaMetafactory`で作られたラムダをサポートしない
この機能を試すためには、`-Xlambdas=indy`コンパイラオプションを追加している。[You Trackチケット](https://youtrack.jetbrains.com/issue/KT-45375)上でフィードバックを共有してもらえるとありがたい。

[Gradle](https://kotlinlang.org/docs/gradle.html#compiler-options)、[Maven](https://kotlinlang.org/docs/maven.html#specifying-compiler-options)、[コマンドラインコンパイラ](https://kotlinlang.org/docs/compiler-reference.html#compiler-options)で、コンパイラオプションを追加する方法を理解する。
## @&#xFFF0;JVMDefaultと古いXjvm-defaultモードの非推奨
Kotlin 1.4.0以前は、`-Xjvm-default=enable`と`-Xjvm-default=compatibility`モードとともに、`@JvmDefault`アノテーションがあった。これらはKotlinインターフェイス内のすべての個々の非抽象メンバ
へJVMデフォルトメソッドを作るために提供されていた。
Kotlin 1.4では、プロジェクト全体でデフォルトメソッドを生成するスイッチである、[新しい`-Xjvm-default`モードが導入された](https://blog.jetbrains.com/kotlin/2020/07/kotlin-1-4-m3-generating-default-methods-in-interfaces/)。
Kotlin 1.5では、`@JvmDefault`と古い`-Xjvm-default`モード、つまり`-Xjvm-default=enable`と`-Xjvm-default=compatibility`が非推奨となっている。
[Java相互運用でのデフォルトメソッドについて、理解を深める](https://kotlinlang.org/docs/java-to-kotlin-interop.html#default-methods-in-interfaces)
## null許容可否アノテーションの扱いの改善
Kotlinでは[null許容可否アノテーション](https://kotlinlang.org/docs/java-interop.html#nullability-annotations)で、Javaからの型のnull許容可否情報を扱うことがサポートされている。Kotlin 1.5.0ではその機能のための多くの改善が導入されている。
- 依存関係として使われているコンパイルされているJavaライブラリ内の、型引数のnull許容アノテーションを読み取る。
- 以下のための、`TYPE_USE`ターゲットのついたnull許容アノテーションをサポートする。
    - 配列
    - 可変長引数
    - フィールド
    - 型パラメータとその境界
    - ベースクラスとインターフェイスの型引数
- もし、null許容アノテーションが型に対して複数のターゲットを持つ場合で、そのうちの一つが`TYPE_USE`の場合、`TYPE_USE`が優先される。例えば、`@Nullable`が`TYPE_USE`と`METHOD`両方をサポートする場合、`@Nullable String[] f()`のメソッドシグネチャは、`fun f(): Array<String?>!`となる。

これらの新しいサポートされるケースのため、KotlinからJavaを呼び出す際に間違った型のnull許容値を使うと警告が生成される。(エラー報告で)これらのケースのための強化モードを有効にするには、`-Xtype-enhancement-improvements-strict-mode`コンパイラオプションを使うこと。
[null安全とプラットフォームの型についての知識を深める](https://kotlinlang.org/docs/java-interop.html#null-safety-and-platform-types)
# 標準ライブラリ
標準ライブラリには、実験的部分の安定化から、新機能の追加まで、幅広い変更と改善がもたらされている。
- 安定した符号なし整数型
- 安定した大文字/小文字テキストのためのロケール非依存API
- 安定したChar型から整数型への変換API
- 安定したPath API
- 切り捨て除算と剰余演算子
- Duration APIの変更
- 文字カテゴリ取得ののための新しいAPIがマルチプラットフォームコードで利用可能
- 新しいコレクション関数であるfirstNotNullOf()
- String?.toBoolean()の厳格バージョン

## 安定した符号なし整数型
`UInt`、`ULong`、`UByte`、`UShort`といった符号なし整数型は今では安定している。これらの型の演算子、範囲、進行についても同様である。符号なし配列とその演算子についてはベータのままである。
[符号なし整数型についての知識を深める](https://kotlinlang.org/docs/basic-types.html#unsigned-integers)

## 安定した大文字/小文字テキストのためのロケール非依存API
このリリースでは、大文字/小文字テキストの変換のための新しいロケール非依存のAPIがもたらされた。ロケール依存である、`toLowerCase()`、`toUpperCase()`、`capitalize()`、`decapitalize()`API関数の代替えを提供する。この新しいAPIにより、異なるロケール設定のためのエラーを回避することができる。
Kotlin 1.5.0は以下の完全に安定した代替えを提供する。
- `String`関数用

|以前のバージョン|1.5.0の代替え|
|---|---|
|`String.toUpperCase()`|`String.upperCase()`|
|`String.toLowerCase()`|`String.lowerCase()`|
|`String.capitalize()`|`String.replaceFirstChar { it.uppercase() }`|
|`String.decapitalize()`|`String.replaceFirstChar { it.lowercase() }`|

- `Char`関数用

|以前のバージョン|1.5.0の代替え|
|---|---|
|`Char.toUpperCase()`|`Char.uppercaseChar():Char`<br>`Char.uppercase(): String`|
|`Char.toLowerCase()`|`Char.lowercaseChar():Char`<br>`Char.lowercase(): String`|
|`Char.toTitleCase()`|`Char.titlecaseChar():Char`<br>`Char.titlecase(): String`|

::: note
Kotlin/JVM用に、明示的に`Locale`パラメータをもつ`upperCase()`、`lowerCase()`、`titleCase()`のオーバーロード関数も存在する。
:::

古いAPI関数は、非推奨の印がついており、将来のリリースで削除されるだろう。
[KEEP](https://github.com/Kotlin/KEEP/blob/master/proposals/stdlib/locale-agnostic-case-conversions.md)にテキスト処理関数の完全な変更リストがある。
##  安定したChar型から整数型への変換API
Kotlin 1.5.0からの、新しいcharからコードとcharから数字変換関数が安定になっている。これらの関数は、同様の文字からint変換と度々混乱する現在のAPI関数を置き換える。
新しいAPIにより、この名前の混乱を除き、コードのふるまいをより透過的に、あいまいさをなくしている。
このリリースでは、`Char`変換が、明確な名前の一連の関数に分かれて導入されている。
- `Char`の整数のコードを受け取り、与えられたコードから`Char`を構築する関数 ※65 ⇔ 'A'
```Kotlin
fun Char(code: Int): Char
fun Char(code: UShort): Char
val Char.code: Int
```
- `Char`をそれが表す数値に変換する関数 ※'0' → 0
```Kotlin
fun Char.digitToInt(radix: Int): Int // ※数値にならない文字は例外
fun Char.digitToIntOrNull(radix: Int): Int? // ※数値にならない文字はnull
```
- 負でない単一桁の数値を`Char`表現に変換する`Int`の拡張関数 ※ 0 → '0'
```Kotlin 
fun Int.digitToChar(radix: Int): Char // 0-9以外は例外
```
[KEEPでcharから整数変換APIについての知識を深める](https://github.com/Kotlin/KEEP/blob/master/proposals/stdlib/char-int-conversions.md)
## 安定したPath API
`java.nio.file.Path`の拡張である、[実験的Path API](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io.path/java.nio.file.-path/)は現在安定である。
```Kotlin
// div (/) 演算子でパスを構築する
val baseDir = Path("/base")
val subDir = baseDir / "subdirectory"

// ディレクトリ内のファイルをリストする
val kotlinFiles: List<Path> = Path("/home/user").listDirectoryEntries("*.kt")
```
[Path APIについての知識を深める](https://kotlinlang.org/docs/whatsnew1420.html#extensions-for-java-nio-file-path)
## 切り捨て除算と剰余演算子
剰余あり除算のための新しい演算子が標準ライブラリに追加された。
- `floorDiv()`は[切り捨て除算](https://en.wikipedia.org/wiki/Floor_and_ceiling_functions)の結果を返す。整数型で利用可能である。
- `mod()`は切り捨て除算の剰余(絶対値)を返却する。これはすべての数値型で利用可能である。
これらの演算子は既存の[整数除算](https://kotlinlang.org/docs/basic-types.html#operations)と[rem()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-int/rem.html)関数(あるいは`%`演算子)にとても良く似ているが、負の数において、異なる動作をする。
- `/`が、0に近づくよう結果を切り捨てるのに対し、`a.floorDiv(b)`は、(より小さい整数に向かって)結果を丸める点で通常の`/`と異なる。
- `a.mod(b)`は`a`と`a.floorDiv(b)`のとの差である。これは`a % b`と異なり、ゼロあるいは`b`と同じ符号を持つ。
```Kotlin
fun main() {
    println("Floored division -5/3: ${(-5).floorDiv(3)}") // -2
    println( "Modulus: ${(-5).mod(3)}") // 1

    println("Truncated division -5/3: ${-5 / 3}") // -1
    println( "Remainder: ${-5 % 3}") // -2
}
```
## Duration APIの変更
::: note alert
Duration APIは、[実験的](https://kotlinlang.org/docs/components-stability.html)である。いつでも削除あるいは変更される可能性がある。評価目的のためにのみ使用してほしい。[You Track](https://youtrack.jetbrains.com/issues/KT)にて、フィードバックを聞ければ幸いである。
:::

実験的[Duration](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.time/-duration/)クラスは異なる時間単位の期間の量を表すためにある。1.5.0では、Duration APIは次の変更がある。
- nowを表すための内部値は、よりよい制度を提供するため、`Double`の代わりに`Long`を使用する
- `Long`で特定の時間単位へ変換するための新しいAPIが存在する。これは`Double`で演算する、今では非推奨の古いAPIを置き換えるためのものである。例えば、[`Duration.inWholeMinutes`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.time/-duration/in-whole-minutes.html)は`Long`で表現される期間の値を返却し、`Duration.inMinutes`を置き換える。
- 数値から`Duration`を組み立てる新しいコンパニオン関数がある。例えば、[`Duration.seconds(Int)`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.time/-duration/seconds.html)は、 整数の秒を表す`Duration`オブジェクトを生成する。`Int.seconds`のような古い拡張プロパティは今は非推奨である。
```Kotlin
import kotlin.time.Duration
import kotlin.time.ExperimentalTime

@ExperimentalTime
fun main() {
    val duration = Duration.milliseconds(120000)
   // There are 120 seconds in 2 minutes
    println("There are ${duration.inWholeSeconds} seconds in ${duration.inWholeMinutes} minutes")
}
```
## 文字カテゴリ取得ののための新しいAPIがマルチプラットフォームコードで利用可能
Kotlin 1.5.0ではUnicodeに従った文字カテゴリを取得する新しいAPIが、マルチプラットフォームプロジェクトで導入されている。今ではいくつかの関数がすべてのプラットフォームで、共通コードで利用可能である。
文字が字か数字をチェックする関数：
- [`Char.isDigit()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/is-digit.html)
- [`Char.isLetter()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/is-letter.html)
- [`Char.isLetterOrDigit()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/is-letter-or-digit.html)
``` Kotlin
fun main() {
    val chars = listOf('a', '1', '+')
    val (letterOrDigitList, notLetterOrDigitList) = chars.partition { it.isLetterOrDigit() }
    println(letterOrDigitList) // [a, 1]
    println(notLetterOrDigitList) // [+]    
}
```
文字の大文字小文字をチェックする関数：
- [`Char.isLowerCase()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/is-lower-case.html)
- [`Char.isUpperCase()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/is-upper-case.html)
- [`Char.isTitleCase()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/is-title-case.html)
```Kotlin
fun main() {
    val chars = listOf('ǅ', 'ǈ', 'ǋ', 'ǲ', '1', 'A', 'a', '+')
    val (titleCases, notTitleCases) = chars.partition { it.isTitleCase() }
    println(titleCases) // [ǅ, ǈ, ǋ, ǲ] ※タイトルケースは合字の1字めが大文字である文字
    println(notTitleCases) // [1, A, a, +]    
}
```
他のいくつかの関数：
- [`Char.isDefined()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/is-defined.html)
- [`Char.isISOControl()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/is-i-s-o-control.html)
 
[`Char.category`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/category.html)プロパティとその戻り値のenumクラスである[`CharCategory`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-char-category/)は、Unicodeに従った文字の一般カテゴリを示し、今はマルチプラットフォームプロジェクトでも有効である。
[文字について知識を深める](https://kotlinlang.org/docs/basic-types.html#characters)
## 新しいコレクション関数であるfirstNotNullOf()
新しい[`firstNotNullOf()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/first-not-null-of.html)と、[`firstNotNullOfOrNull()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/first-not-null-of-or-null.html)関数は、[`mapNotNull()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map-not-null.html)に[`first()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/first.html)あるいは、[`firstOrNull()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/first-or-null.html)を合わせている。これらは元のコレクションにカスタムなセレクタ関数をmapし、最初のnullでない値を戻す。もしそのような値が無い場合、[`firstNotNullOf()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/first-not-null-of.html)は例外をスローし、[`firstNotNullOfOrNull()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/first-not-null-of-or-null.html)はnullを戻す。
```Kotlin
fun main() {
    val data = listOf("Kotlin", "1.5")
    println(data.firstNotNullOf(String::toDoubleOrNull)) // 1.5
    println(data.firstNotNullOfOrNull(String::toIntOrNull)) // null
}
```
## String?.toBoolean()の厳格バージョン
２つの新しい関数により、既存の[`String?.toBoolean()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/to-boolean.html)の大文字小文字を考慮した厳格なバージョンがもたらされた。
- [`String.toBooleanStrict()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/to-boolean-strict.html)は、入力値が`true`と`false`以外のものに対して例外をスローする。
- [`String.toBooleanStrictOrNull()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/to-boolean-strict-or-null.html)は、入力値が`true`と`false`以外のものに対してnullを戻す。
```Kotlin
fun main() {
    println("true".toBooleanStrict()) // true
    println("1".toBooleanStrictOrNull()) // null
    // println("1".toBooleanStrict()) // 例外    
}
```
# kotlin-testライブラリ
[`kotlin-test`](https://kotlinlang.org/api/latest/kotlin.test/)ライブラリに、いくつかの機能が導入されている。
- マルチプラットフォームプロジェクトでのテスト依存関係の使い方の簡素化
- Kotlin/JVM用のテストフレームワークの自動的な選択
- アサーション関数の更新
## マルチプラットフォームプロジェクトでのテスト依存関係の使い方の簡素化
今では、`commonTest`ソースセット内でテストするための依存性の追加に、`kotlin-test`依存性を使うことができる。そしてGradleプラグインは、それぞれのテストソースセットのために対応するプラットフォーム依存性を推測する。
- JVMソースセットのための`kotlin-test-junit`。[Kotlin/JVMのための、テストフレームワークの自動化された選択](https://kotlinlang.org/docs/whatsnew15.html#automatic-selection-of-a-testing-framework-for-kotlin-jvm-source-sets)を参照。
- Kotlin/JSのための`kotlin-test-js`
- 共通ソースセットのための`kotlin-test-common`と`kotlin-test-annotations-common`
- Kotlin/Nativeソースセットのための追加の成果物は無し
-さらに、`kotlin-test`依存性をどのような共有あるいはプラットフォーム指定のソースセットにも、使うことができる。
明示的な依存関係のある、既存のkotlin-test構成は、GradleとMaven両方で動作し続けるだろう。
[テストライブラリにおける依存性の設定](https://kotlinlang.org/docs/gradle.html#set-dependencies-on-test-libraries)についての知識を深める
## Kotlin/JVM用のテストフレームワークの自動的な選択
Gradleプラグインは今では自動的にテストフレームワークに関する依存性を選択し、追加する。必要なのは、共通ソースセットで`kotlin-test`の依存性を追加するだけである。
GradleはデフォルトでJUnit 4を使用する。そのため、`kotlin("test")`の依存性はJUnit 4の変形、つまり`kotlin-test-junit`を解決する。
```Kotlin
kotlin {
    sourceSets {
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test")) // これはJUnit 4についての依存性を他動的にもたらす
            }
        }
    }
}
```
[`useJUnitPlatform()`](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/testing/Test.html#useJUnitPlatform)または[`useTestNG()`](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/testing/Test.html#useTestNG)をtestタスクで呼ぶことで、JUnit5またはTestNGを選択することができる。
```Kotlin
tasks {
    test {
        // enable TestNG support
        useTestNG()
        // or
        // enable JUnit Platform (a.k.a. JUnit 5) support
        useJUnitPlatform()
    }
}
```
プロジェクトの`gradle.properties`に`kotlin.test.infer.jvm.variant=false`の行を追加することで、自動的なテストフレームワークの選択を無効にすることができる。
[テストライブラリについての依存性を設定する](https://kotlinlang.org/docs/gradle.html#set-dependencies-on-test-libraries)ことについての知識を深める。

## アサーション関数の更新
このリリースでは、新しいアサーション関数と既存の関数の改善がもたらされている。
`kotlin-test`ライブラリは、今では次の機能を持っている。

- 値の型チェック
値の型をチェックするために新しい`assertIs<T>`と`assertIsNot<T>`を使うことができる。
```Kotlin
@Test
fun testFunction() {
    val s: Any = "test"
    assertIs<String>(s)  // もしアサーションが失敗すると、実際の型を言及する例外をスローする
    // assertIsの規約のため、s.lengthを出力することができる。
    println("${s.length}")
}
```
型消去のため、このアサーション関数では、次の例で、`value`が`List`型かどうかをチェックするのみで、特に`String`の要素型のリストかどうかはチェックしない。`assertIs<List<String>>(value)`
- 配列、シーケンス、任意のiterableのためのコンテナの内容物の比較
[構造的な等価性](https://kotlinlang.org/docs/equality.html#structural-equality)を実装していない、異なるコレクションの内容を比較するため、一連のオーバーロードされた`assertContentEquals()`関数が存在する。
```Kotlin
@Test
fun test() {
    val expectedArray = arrayOf(1, 2, 3)
    val actualArray = Array(3) { it + 1 }
    assertContentEquals(expectedArray, actualArray)
}
```
- `Double`や`Float`の数値のための、`assertEquals()`と`assertNotEquals()`の新しいオーバーロード
絶対精度で二つの`Double`や`Float`の数値を比較することを可能にする、`assertEquals()`関数の新しいオーバーロードが存在する。制度の値は、関数の三つ目のパラメータで指定する。
```Kotlin
@Test
fun test() {
    val x = sin(PI)

    // 精度パラメータ
    val tolerance = 0.000001

    assertEquals(0.0, x, tolerance)
}
```
- コレクションの内容と要素をチェックする新しい関数
今では、コレクションや要素が、何かを含むかどうかを、`assertContains()`関数でチェックすることができる。`IntRange`、`String`など、`contains()`演算子を持つ、コレクションや要素とともに使うことができる。
```Kotlin
@Test
fun test() {
    val sampleList = listOf<String>("sample", "sample2")
    val sampleString = "sample"
    assertContains(sampleList, sampleString)  // コレクション内の要素
    assertContains(sampleString, "amp")       // 文字列の部分文字列
}
```
- `assertTrue()`、`assertFalse()`、`expect()`関数が今ではinline化
今から、これらをインライン関数で使うことができるため、ラムダ表記の内部で、[suspend関数](https://kotlinlang.org/docs/composing-suspending-functions.html)を呼び出すことができる。
```Kotlin
@Test
fun test() = runBlocking<Unit> {
    val deferred = async { "Kotlin is nice" }
    assertTrue("Kotlin substring should be present") {
        deferred.await() .contains("Kotlin")
    }
}
```

# kotlinxライブラリ
Kotlin 1.5.0とともに、新しいバージョンのkotlinxライブラリがリリースされている。
- `kotlinx.coroutines` [1.5.0-RC](https://kotlinlang.org/docs/whatsnew15.html#coroutines-1-5-0-rc)
- `kotlinx.serialization` [1.2.1](https://kotlinlang.org/docs/whatsnew15.html#serialization-1-2-1)
- `kotlinx-datetime` [0.2.0](https://kotlinlang.org/docs/whatsnew15.html#datetime-0-2-0)

## coroutines 1.5.0-RC
`kotlinx.coroutines` [1.5.0-RC](https://kotlinlang.org/docs/whatsnew15.html#coroutines-1-5-0-rc)では、以下の機能とともにやってきた。
- [新しいchannels API](https://kotlinlang.org/docs/channels.html)
- 安定した[reactive統合](https://kotlinlang.org/docs/async-programming.html#reactive-extensions)
- 等々
Kotlin 1.5.0より、[実験的なcoroutine](https://kotlinlang.org/docs/whatsnew14.html#exclusion-of-the-deprecated-experimental-coroutines)は無効であり、`-Xcoroutines=experimental`フラグはもはやサポートされていない。
[改定履歴](https://github.com/Kotlin/kotlinx.coroutines/releases/tag/1.5.0-RC)と、[`kotlinx.coroutines` 1.5.0のリリースブログ投稿](https://blog.jetbrains.com/kotlin/2021/05/kotlin-coroutines-1-5-0-released/)で知識を深める

## serialization 1.2.1
`kotlinx.serialization` [1.2.1](https://github.com/Kotlin/kotlinx.serialization/releases/tag/v1.2.1)では、以下の機能とともにやってきた。
- JSONシリアライズ性能の向上
- JSONシリアライズでの複数の名前のサポート
- `@Serializable`クラスからの実験的な.protoスキーマ生成
- 等々
[改定履歴](https://github.com/Kotlin/kotlinx.serialization/releases/tag/v1.2.1)と、[`kotlinx.serialization` 1.2.1のリリースブログ投稿](https://blog.jetbrains.com/kotlin/2021/05/kotlinx-serialization-1-2-released/)で知識を深める
## dateTime 0.2.0
`kotlinx-datetime` [0.2.0](https://github.com/Kotlin/kotlinx-datetime/releases/tag/v0.2.0)では、以下の機能とともにやってきた。
- DateTimeオブジェクトの`@Serializable`
- `DateTimePeriod`と`DatePeroid`の正常化されたAPI
- 等々
[改定履歴](https://github.com/Kotlin/kotlinx-datetime/releases/tag/v0.2.0)と、[`kotlinx-datetime` 0.2.0のリリースブログ投稿](https://blog.jetbrains.com/kotlin/2021/05/kotlinx-datetime-0-2-0-is-out/)で知識を深める
# Kotlin 1.5.0への移行
IntelliJ IDEAとAndroid StudioはKotlinプラグイン1.5.0が利用可能になれば、アップグレードすることを提案するだろう。
既存のプロジェクトをKotlin 1.5.0に移行するためには、Kotlinバージョンを1.5.0に変更してGradleまたはMavenプロジェクトを再インポートするのみである。[Kotlin 1.5.0への更新方法を学ぶ](https://kotlinlang.org/docs/releases.html#update-to-a-new-release)
Kotlin 1.5.0で新しいプロジェクトを開始するには、Kotlinプラグインを更新し、**ファイル|新規|プロジェクト**から、プロジェクトウィザードを実行すること。
新しいコマンドラインコンパイラが、[GitHubリリースページ](https://github.com/JetBrains/kotlin/releases/tag/v1.5.0)でダウンロードすることで利用可能である。
Kotlin 1.5.0は[機能リリース](https://kotlinlang.org/docs/kotlin-evolution.html#feature-releases-and-incremental-releases)であり、そのため言語に互換性の無い変更をもたらすことがある。そのような変更のリストの詳細は、[Kotlin 1.5互換性ガイド](https://kotlinlang.org/docs/compatibility-guide-15.html)にある。