Kotlin 1.8.20の変更点

※[ソース記事](https://kotlinlang.org/docs/whatsnew1820.html)
※Kotlin/JS、Kotlin/Nativeについては割愛します。
[リリース日：2023/4/3](https://kotlinlang.org/docs/releases.html#release-details)
Kotlin 1.8.20のリリースが公開され、こちらに最大のハイライトのいくつかがある。
- 新しいKotlin K2コンパイラの更新
- 新しい実験的Kotlin/Wasmターゲット
- Gradleでの新しいJVMの増分コンパイルがデフォルト化
- Kotlin/Nativeターゲットの更新
- Kotlin MultiplatformにおけるGradle複合ビルドのプレビュー
- XcodeにおけるGradleエラー出力の改善
- 標準ライブラリにおけるAutoCloseableインターフェイスの実験的サポート
- 標準ライブラリにおけるBase64エンコーディングの実験的サポート
こちらの映像で、変更点の短い概要をみつけることができる。
<iframe width="558" height="314" src="https://www.youtube.com/embed/R1JpkpPzyBU" title="What&#39;s new in Kotlin 1.8.20: K2 compiler, language updates, stdlib improvements, and Java interop" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

# IDEのサポート
1.8.20をサポートするKotlinプラグインは以下。
|IDE  |サポートバージョン  |
|---|---|
|IntelliJ IDEA  |2022.2.x, 2022.3.x, 2023.1.x  |
|Android Studio  |Flamingo (222)  |

:::note warn
Kotlin成果物と依存関係を適切にダウンロードするためには、Maven Centralリポジトリを使うために[Gradle設定を行うこと](https://kotlinlang.org/docs/whatsnew1820.html#configure-gradle-settings)
:::
# 新しいKotlin K2コンパイラの変更点

KotlinチームはK2コンパイラの安定化を継続している。[Kotlin 1.7.0のアナウンス](https://kotlinlang.org/docs/whatsnew17.html#new-kotlin-k2-compiler-for-the-jvm-in-alpha)で述べたように、まだ**Alpha**である。このリリースでは[K2 Beta](https://youtrack.jetbrains.com/issue/KT-52604)への道におけるさらなる改善が導入されている。
この1.8.20リリースからKotlin K2コンパイラでは、以下が行われている。
- serializationプラグインのプレビュー版
- [JS IRコンパイラ](https://kotlinlang.org/docs/js-ir-compiler.html)のAlphaサポートの提供
- [新しい言語バージョンであるKotlin 2.0](https://blog.jetbrains.com/kotlin/2023/02/k2-kotlin-2-0/)の将来のリリースの紹介
新しいコンパイラとその利点について、次の映像で知識を深める。
- [皆さんが新しいKotlin K2コンパイラについて知らなければならないこと](https://www.youtube.com/watch?v=iTdJJq_LyoY)
- [新しいKotlin K2コンパイラ エキスパートレビュー](https://www.youtube.com/watch?v=db19VFLZqJM)

## Kotlin K2コンパイラの有効化方法
Kotlin K2コンパイラを有効化し、テストするためには、次のコンパイラオプションで新しい言語バージョンを使う。
```
-language-version 2.0
```
```build.gradle(.kts)```ファイルで、指定することができる。
```
kotlin {
   sourceSets.all {
       languageSettings {
           languageVersion = "2.0"
       }
   }
}
```
以前の```-Xuse-k2```コンパイラオプションは非推奨になった。

:::note warn
新しいKotlin K2コンパイラのAlphaバージョンは、JVMとJS IRプロジェクトでのみ動作する。Kotlin/Nativeやマルチプラットフォームプロジェクトはサポートされていない。
:::
## 新しいK2コンパイラにおけるフィードバック
是非ご意見をお聞かせください！
- Kotlin Slackで直接K2開発者へフィードバックを提供 - [招待を受け](https://surveys.jetbrains.com/s3/kotlin-slack-sign-up?_gl=1*ju6cbn*_ga*MTA3MTk5NDkzMC4xNjQ2MDY3MDU4*_ga_9J976DJZ68*MTY1ODMzNzA3OS4xMDAuMS4xNjU4MzQwODEwLjYw)、[#k2-early-adopters](https://kotlinlang.slack.com/archives/C03PK0PE257)チャンネルに参加
- [我々のissue tracker](https://kotl.in/issue)で、新しいK2コンパイラで直面した問題を報告
- [利用統計の送信オプションを有効化](https://www.jetbrains.com/help/idea/settings-usage-statistics.html)し、JetBrainsにK2利用についての匿名データの収集を許可する。

# 言語
Kotlinが進化し続けるように、我々は1.8.20で新しい言語機能のためのプレビューバージョンを導入している。
- Enumクラス値関数のモダンで高性能な代替
- dataクラスと調和するためのdataオブジェクトのプレビュー
- インラインクラスでの本体を持つセカンダリコンストラクタの制限の撤廃

## Enumクラス値関数のモダンで高性能な代替
::: note warn
この機能は実験的である。いつでも削除あるいは変更される可能性がある。オプトインが必要(以下参照)である。評価目的のためにのみ使用すること。[YouTrack](https://kotl.in/issue)上でご意見をお聞かせください。
:::
Enumクラスは合成```values()```関数を持ち、定義されたenum定数の配列を返却する。しかし、配列を使うことはKotlinとJavaでに[隠れた性能問題](https://github.com/Kotlin/KEEP/blob/master/proposals/enum-entries.md#examples-of-performance-issues)を引き起こすことがある。さらにほとんどのAPIはコレクションを使い、最終的に変換が必要である。これらの問題を修正するため、Enumクラスのための```entries```プロパティを導入し、```values()```関数の代わりに使うべきとした。呼び出し時に、```entries```プロパティは、事前割り当てされた定義されたenum定数の変更できないリストを返却する。

::: note info
```values()```関数は引き続きサポートされるが、```entries```プロパティを代わりに使用することを推奨する。 
:::
```Kotlin
enum class Color(val colorName: String, val rgb: String) {
   RED("Red", "#FF0000"),
   ORANGE("Orange", "#FF7F00"),
   YELLOW("Yellow", "#FFFF00")
}


@OptIn(ExperimentalStdlibApi::class)
fun findByRgb(rgb: String): Color? = Color.entries.find { it.rgb == rgb }
```

### entriesプロパティの有効化方法
この機能を試すには、```@OptIn(ExperimentalStdlibApi)```でオプトインを行い、```language-version 1.9```コンパイラオプションを有効にすること。Gradleプロジェクトでは、build.gradle.ktsに以下を追加することで可能となる。
```kotlin
tasks
    .withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask<*>>()
    .configureEach {
        compilerOptions
            .languageVersion
            .set(
                org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9
            )
    }
```

::: note info
IntelliJ IDEA 2023.1から、この機能に対してオプトインした場合、適切にIDEが```values()```から```entries```への変換を通知し、クイックフィックスを提示する。
:::

この提案の詳細は、[KEEP note](https://github.com/Kotlin/KEEP/blob/master/proposals/enum-entries.md)を参照のこと。
## data classと調和するためのdata objectのプレビュー
data objectはシングルトンの意味と簡潔な```toString()```表現を持つobjectを宣言することが可能になる。このスニペットでは、object宣言に```data```キーワードを追加することで、```toString()```出力の可読性を向上することがわかる。
```Kotlin
package org.example
object MyObject
data object MyDataObject

fun main() {
    println(MyObject) // org.example.MyObject@1f32e575
    println(MyDataObject) // MyDataObject
}
```
特に(```sealedクラス```や```sealedインターフェイス```階層のような)```sealed```階層には、```data object```は```data class```宣言と便利に並んで使うことができるため、ぴったりフィットする。このスニペットでは、プレーンな```object```の代わりに```dataオブジェクト```として、```EndOfFile```を宣言することで、手動でオーバーライドする必要なく、美しい```toString```を得ることができる。これは付属のdata class宣言との調和を維持する。
```Kotlin
sealed interface ReadResult
data class Number(val number: Int) : ReadResult
data class Text(val text: String) : ReadResult
data object EndOfFile : ReadResult

fun main() {
    println(Number(7)) // Number(number=7)
    println(EndOfFile) // EndOfFile
}
```
### data objectの意味合い
[Kotlin 1.7.20](https://kotlinlang.org/docs/whatsnew1720.html#improved-string-representations-for-singletons-and-sealed-class-hierarchies-with-data-objects)での最初のプレビューバージョンから、data objectの意味合いが改良された。今ではコンパイラによって、多くの便利な関数が生成される。
#### toString
data objectの```toString()```関数はオブジェクトの単純な名前を返却する。
```Kotllin
data object MyDataObject {
    val x: Int = 3
}

fun main() {
    println(MyDataObject) // MyDataObject
}
```
#### equalsとhashCode
data objectの```equals()```関数は```あるdataオブジェクト```の型を持つすべてのオブジェクトが等しいと評価されることを保証する。ほとんどの場合、実行時にあるdataオブジェクトの単一のインスタンスを持つだけであろう(要するに```dataオブジェクト```はシングルトンを宣言する)。しかし、同じ型の異なるオブジェクトが実行時に生成されるエッジケース(例えば、```java.lang.reflect```を通じたプラットフォームリフレクション経由や、内部でこのAPIを使うJVMのシリアライズライブラリの利用による)では、そのオブジェクトは等しいものとして扱われることを保証する。
注意すべきは、```data object```を構造的(```==```演算子使用)に比較し、参照(```===```演算子使用)で比較しないということだけである。これにより、実行時にdata objectの複数のインスタンスが存在するときに落とし穴を避けることができる。以下のスニペットでこの特定のエッジケースを例示する。
```Kotlin
import java.lang.reflect.Constructor

data object MySingleton

fun main() {
    val evilTwin = createInstanceViaReflection()

    println(MySingleton) // MySingleton
    println(evilTwin) // MySingleton

    // 例えライブラリがMySingletonの二つ目のインスタンスを強制的に作っても`equals`はtrueを返す:
    println(MySingleton == evilTwin) // true

    // ===経由でdata objectを比較しないこと。
    println(MySingleton === evilTwin) // false
}

fun createInstanceViaReflection(): MySingleton {
    // Kotlinのリフレクションでは、data objectのインスタンス化は許可されていない。
    // ここでは新しいMySingletonのインスタンスを「力ずくで」作る。(例 Javaプラットフォームのリフレクション)
    // このようなことはしないこと！
    return (MySingleton.javaClass.declaredConstructors[0].apply { isAccessible = true } as Constructor<MySingleton>).newInstance()
}
```
生成された```hashCode()```関数のふるまいは```equals()```関数のものと一致しており、そのため、ある```data object```のすべての実行時インスタンスは、同じハッシュコードを持つ。
#### data objectのcopyとcomponentN関数は無い
```data object```と```data class```宣言は度々一緒に使用し、いくつか類似点を持つ一方で、いくつかの関数は```data object```には生成されない。
```data object```宣言はシングルトンオブジェクトとして使うことを意図しているため、```copy()```関数は生成されない。シングルトンパターンはクラスのインスタンス化を単一のインスタンスに制限するので、インスタンスのコピー作成を許可することは、その制限に違反するだろう。
また、```data class```と異なり、```data object```はdataプロパティを一つも持たない。そのようなオブジェクトを分解しようとすることは意味がないため、```componentN()```関数は生成されない。
[YouTrack](https://youtrack.jetbrains.com/issue/KT-4107)でこの機能についてのご意見をお聞かせください。
#### data objectプレビューの有効化方法
この機能を試すには、```-language-version 1.9```コンパイラオプションを有効にすること。Gradleプロジェクトでは、build.gradle.ktsに以下を追加することで可能となる。
```kotlin
tasks
    .withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask<*>>()
    .configureEach {
        compilerOptions
            .languageVersion
            .set(
                org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9
            )
    }
```
### インラインクラスでの本体を持つセカンダリコンストラクタの制限の撤廃
::: note warn
この機能は実験的である。いつでも削除あるいは変更される可能性がある。オプトインが必要(以下参照)である。評価目的のためにのみ使用すること。[YouTrack](https://kotl.in/issue)上でご意見をお聞かせください。
:::
Kotlin 1.8.20では、[インラインクラス](https://kotlinlang.org/docs/inline-classes.html)での本体を持つセカンダリコンストラクタの使用制限が撤廃されている。
インラインクラスは、`init`ブロックの無いpublicプライマリコンストラクタあるいはセカンダリコンストラクタのみが、明確な初期化の意味合いを持つことをかつて許可されていた。結果として根底にある値をカプセル化することや制約のある値を表すインラインクラスを作ることが不可能だった。
これらの問題はKotlin 1.4.30が```init```ブロックの制限を撤廃することで修正された。現在は一歩進め、プレビューモードで本体を持つセカンダリコンストラクタを許可している。
```Kotlin
@JvmInline
value class Person(private val fullName: String) {
// Kotlin 1.4.30から許可された:
    init {
        check(fullName.isNotBlank()) {
            "Full name shouldn't be empty"
        }
    }
// Kotlin 1.8.20からプレビューが利用可能:
    constructor(name: String, lastName: String) : this("$name $lastName") {
        check(lastName.isNotBlank()) {
            "Last name shouldn't be empty"
        }
    }
}
```
#### 本体を持つセカンダリコンストラクタの有効化方法
この機能を試すには、```-language-version 1.9```コンパイラオプションを有効にすること。Gradleプロジェクトでは、build.gradle.ktsに以下を追加することで可能となる。
```kotlin
tasks
    .withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask<*>>()
    .configureEach {
        compilerOptions
            .languageVersion
            .set(
                org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9
            )
    }
```
この機能を試し、[YouTrack](https://kotl.in/issue)ですべての報告を提出することをお勧めする。そうすればKotlin1.9.0でデフォルトにすることができる。
Kotlinのinclineクラスの開発について詳しくは[このKEEP](https://github.com/Kotlin/KEEP/blob/master/proposals/inline-classes.md)をご覧ください。
# 新しいKotlin/WASMターゲット
Kotlin/Wasm (Kotlin WebAssembly)はこのプレビューリリースで[実験的](https://kotlinlang.org/docs/components-stability.html#stability-levels-explained)になっている。Kotlinチームは[WebAssembly](https://webassembly.org/)が将来性のある技術であることを見出し、それを使い、Kotlinのすべての利点を得るためのより良い方法を見つけたいと思っている。
WebAssemblyバイナリフォーマットは自身のVMで動作するため、プラットフォーム独立である。ほぼすべてのブラウザはWebAssemblly 1.0をすでにサポートしている。WebAssembllyを実行するための環境をセットアップするには、Kotlin/WASMがターゲットとする実験的ガベージコレクションモードを有効にする必要があるだけである。詳細な手順はこちらで見つけることができる。[Kotlin/WASMの有効化方法](https://kotlinlang.org/docs/whatsnew1820.html#how-to-enable-kotlin-wasm)
新しいKotlin/WASMターゲットの次の利点を強調したい。
- Kotlin/WASMはLLVMを使用しないため、```wasm32``` Kotlin/Nativeターゲットに比べて、より高速なコンパイル。
- [Wasmガベージコレクション](https://github.com/WebAssembly/gc)のおかげで、```wasm32```ターゲットよりもJSとの簡単な相互運用性とブラウザとの統合。
- WASMがコンパクトな解析しやすいバイトコードを持つため、Kotlin/JSとJavascriptよりも潜在的により速いアプリケーション起動。
- WASMが静的な言語であるため、Kotlin/JSとJavascriptよりも実行時の性能が改善されること。

1.8.20-RC2のプレビューリリースから、実験的なプロジェクトでえ、Kotlin/WASMを使うことができる。Kotlin/WASM用のKotlin標準ライブラリ(```stdlib```)とテストライブラリ(```kotlin.test```)が設定なしで提供されている。IDEのサポートは将来のリリースで追加されるだろう。
[Kotlin/WASMについて詳しくはこのYouTube映像でご覧ください。](https://www.youtube.com/watch?v=-pqz9sKXatw)
## Kotlin/WASMの有効化方法
Kotlin/WASMを有効化し試すには、```build.gradle.kts```ファイルを更新すること。
```Kotlin
plugins {
    kotlin("multiplatform") version "1.8.20-RC2"
}

kotlin {
    wasm {
        binaries.executable()
        browser {
        }
    }
    sourceSets {
        val commonMain by getting
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test"))
            }
        }
        val wasmMain by getting
        val wasmTest by getting
    }
}
```

::: note
[Kotlin/WASMのサンプルGitHubリポジトリ](https://github.com/Kotlin/kotlin-wasm-examples)をチェックしてください。
:::
Kotlin/WASMプロジェクトを実行するには、対象の環境設定を更新する必要がある。
### Chrome
- バージョン109用
  ```--js-flags=--experimental-wasm-gc```コマンドライン引数でアプリケーションを実行する。
- バージョン110以上用
  1. ブラウザで、```chrome://flags/#enable-webassembly-garbage-collection```に遷移する
  1. **WebAssembly Garbage Collection**を有効にする
  1. ブラウザを再起動する
### Firefox
- バージョン109以上用
  1. ブラウザで、```about:config```に遷移する
  1. ```javascript.options.wasm_function_references```と```javascript.options.wasm_gc```を有効にする
  1. ブラウザを再起動する

### Edge
- バージョン109以上用
  ```--js-flags=--experimental-wasm-gc```コマンドライン引数でアプリケーションを実行する。
### Kotlin/WASMにおけるフィードバック
是非ご意見をお聞かせください！
- Kotlin Slackで直接開発者へフィードバックを提供 - [招待を受け](https://surveys.jetbrains.com/s3/kotlin-slack-sign-up?_gl=1*ju6cbn*_ga*MTA3MTk5NDkzMC4xNjQ2MDY3MDU4*_ga_9J976DJZ68*MTY1ODMzNzA3OS4xMDAuMS4xNjU4MzQwODEwLjYw)、[#webassembly](https://kotlinlang.slack.com/archives/CDFP59223)チャンネルに参加
- [我々のissue tracker](https://kotl.in/issue)で、Kotlin/WASMで直面した問題を報告
# Kotlin/JVM
Kotlin 1.8.20では、Javaの合成プロパティ参照のプレビューと、kaptスタブ生成タスクのJVM IRバックエンドのデフォルトサポートが導入されている。
## Javaの合成プロパティ参照のプレビュー
::: note warn
この機能は実験的である。いつでも削除あるいは変更される可能性がある。評価目的のためにのみ使用すること。[YouTrack](https://kotl.in/issue)上でご意見をお聞かせください。
:::
Kotlin 1.8.20ではJavaの合成プロパティへの参照をつくる機能が導入されている。例えばこんなJavaコードである。
```Java
public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}
```
Kotlinでは常に```person.age```を書くことが許可されてきた。そこでは```age```は合成プロパティである。現在、```Person::age```と```person::age```への参照を作ることもできる。```name```に対してもまったく同様に動作する。
```Kotlin
val persons = listOf(Person("Jack", 11), Person("Sofie", 12), Person("Peter", 11))
    Persons
        // Javaの合成プロパティへの参照呼び出し:
        .sortedBy(Person::age)
        // Kotlinのプロパティ文法経由でのJavaのゲッター呼び出し:
        .forEach { person -> println(person.name) }
}
```
###  Javaの合成プロパティ参照の有効化方法
この機能を試すには、```-language-version 1.9```コンパイラオプションを有効にすること。Gradleプロジェクトでは、build.gradle.ktsに以下を追加することで可能となる。
```kotlin
tasks
    .withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask<*>>()
    .configureEach {
        compilerOptions
            .languageVersion
            .set(
                org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9
            )
    }
```
## kaptスタブ生成タスクのJVM IRバックエンドのデフォルトサポート
Kotlin 1.7.20で、[kaptスタブ生成タスクのJVM IRバックエンドのサポート](https://kotlinlang.org/docs/whatsnew1720.html#support-for-the-jvm-ir-backend-in-kapt-stub-generating-task)が導入された。今回のリリースから、このサポートはデフォルトで動作する。もはやそれを有効化するために、```gradle.properties```で```kapt.use.jvm.ir=true```を指定する必要は無い。この機能について[YouTrack](https://youtrack.jetbrains.com/issue/KT-49682)上でご意見をお聞かせください。
# Gradle
Kotlin 1.8.20はいくつかの[Multiplatformプラグインでの特別なケース](https://youtrack.jetbrains.com/issue/KT-55751?_ga=2.242561090.1572773554.1681091178-1843946880.1681091178&_gl=1*m9a1s7*_ga*MTg0Mzk0Njg4MC4xNjgxMDkxMTc4*_ga_9J976DJZ68*MTY4MTA5MTE3Ny4xLjEuMTY4MTA5MTIyNy4yNi4wLjA.)を除いてGradle 6.8から7.6までと完全に互換性がある。最新のGradleリリースまでGradleバージョンを上げて使うこともできるが、その場合、非推奨警告に直面するか、いくつかの新しいGradle機能が動作しない可能性があることに注意すること。
このバージョンでは以下の変更がもたらされている。
- Gradleプラグインのバージョンの新しい統一
- Gradleでの新しいJVM差分コンパイルのデフォルト化
- コンパイルタスクの出力の正確なバックアップ
- 全Gradleバージョン用の遅延Kotlin/JVMタスク生成
- コンパイルタスクの宛先ディレクトリのデフォルト以外の場所
- HTTP統計サービスへコンパイル引数を報告回避する機能

## Gradleプラグインのバージョンの新しい統一
Gradleは共に動作しなければならない依存性が常に[バージョンが統一されていること](https://docs.gradle.org/current/userguide/dependency_version_alignment.html#aligning_versions_natively_with_gradle)を保証する方法を提供している。Kotlin 1.8.20でもこのアプローチを採用した。それはデフォルトで動作し、有効にするために構成を変更したり、更新する必要はない。さらに[Kotlin Gradleプラグインの推移的依存性を解決するための回避策](https://kotlinlang.org/docs/whatsnew18.html#resolution-of-kotlin-gradle-plugins-transitive-dependencies)に頼る必要はもう無い。
この機能について[YouTrack](https://youtrack.jetbrains.com/issue/KT-54691?_ga=2.242630594.1572773554.1681091178-1843946880.1681091178&_gl=1*ww1jex*_ga*MTg0Mzk0Njg4MC4xNjgxMDkxMTc4*_ga_9J976DJZ68*MTY4MTA5MTE3Ny4xLjEuMTY4MTA5Mjc5Ni4zMC4wLjA.)でご意見をお聞かせください。
## Gradleでの新しいJVM差分コンパイルのデフォルト化
差分コンパイルの新しアプローチは、[Kotlin 1.7.0から利用可能であった](https://kotlinlang.org/docs/whatsnew17.html#a-new-approach-to-incremental-compilation)が、現在ではデフォルトで動作する。有効にするために```gradle.properties```に```kotlin.incremental.useClasspathSnapshot=true```を指定する必要はもう無い。
このことについてご意見をお聞かせください。YouTrackで[問題を報告](https://kotl.in/issue)することができる。
## コンパイルタスクの出力の正確なバックアップ
::: note warn
コンパイルタスクの出力の正確なバックアップは実験的である。使うには、```gradle.properties```に```kotlin.compiler.preciseCompilationResultsBackup=true```を追加すること。[YouTrack](https://kotl.in/issue/experimental-ic-optimizations)でご意見をお聞かせください。
:::
Kotlin 1.8.20から、正確なバックアップを有効にすることができ、それによって、Kotlinが[差分コンパイル](https://kotlinlang.org/docs/gradle-compilation-and-caches.html#incremental-compilation)でリコンパイルするクラス群のみが、バックアップされるようになる。フルおよび正確なバックアップにより、コンパイルエラーの後で再度差分的にビルドを実行することができる。正確なバックアップは、フルバックアップに比べてビルド時間も節約する。フルバックアップは巨大なプロジェクト、あるいは多くのタスクがバックアップを行っている場合、あるいはプロジェクトが遅いHDDに配置されている場合特に、**著しく**時間がかかるかもしれない。
この最適化は実験的である。```gradle.properties```ファイルに```kotlin.compiler.preciseCompilationResultsBackup```Gradleプロパティを追加することで有効にすることができる。
```
kotlin.compiler.preciseCompilationResultsBackup=true
```
※[こちら](https://kotlinlang.org/docs/whatsnew1820.html#precise-backup-of-compilation-tasks-outputs)に、JetBrainsでの正確なバックアップの例と、ビルドレポートを使った最適化の評価が記載されています。

## 全Gradleバージョン用の遅延Kotlin/JVMタスク生成
Gradle 7.3以上の"org.jetbrains.kotlin.gradle.jvm"プラグインを使ったプロジェクト用に、Kotlin Gradleプラグインは"compileKotlin"タスクを積極的に作り、設定することはもう無い。より古いGradleバージョンでは、すべてのタスクを単に登録し、リハーサルで設定を行わない。現在、同じ振る舞いがGradle 7.3以上を使うときに導入されている。
## コンパイルタスクの宛先ディレクトリのデフォルト以外の場所
次のうちの一つをする場合、いくつかの追加コードでビルドスクリプトを更新すること。
- Kotlin/JVMの```KotlinJvmCompile```/```KotlinCompile```タスクの```destinationDirectory```の場所を上書きすること
- 非推奨のKotlin/JS/Non-IR[バリアント](https://kotlinlang.org/docs/gradle-plugin-variants.html)を使い、```Kotlin2JsCompile```タスクの```destinationDirectory```を上書きすること

JARファイル内の```sourceSets.main.outputs```に```sourceSets.main.kotlin.classesDirectories```を明示的に追加する必要がある。
```tasks.jar(type: Jar) { from sourceSets.main.outputs from sourceSets.main.kotlin.classesDirectories }```
## HTTP統計サービスへコンパイル引数を報告回避する機能
現在、Kotlin Gradleプラグインが、HTTP[ビルドレポート](https://kotlinlang.org/docs/gradle-compilation-and-caches.html#build-reports)にコンパイル引数を含むべきかを制御することができるようになった。時々、プラグインがこれらの引数を報告する必要が無いかもしれない。プロジェクトが多くのモジュールを含む場合、レポート内のコンパイル引数が非常に重くなり、役立たないことがありうる。現在は、それを無効にする方法があり、それによりメモリを節約する。```gradle.properties```あるいは```local.properties```で、```kotlin.build.report.include_compiler_arguments=(true|false)```を使うこと。
[YouTrack](https://youtrack.jetbrains.com/issue/KT-55323/?_ga=2.243105602.1572773554.1681091178-1843946880.1681091178&_gl=1*8dm8ie*_ga*MTg0Mzk0Njg4MC4xNjgxMDkxMTc4*_ga_9J976DJZ68*MTY4MTA5MTE3Ny4xLjEuMTY4MTA5NDgwNi42MC4wLjA.)でこの機能について、ご意見をお聞かせください。
# 標準ライブラリ
Kotlin 1.8.20では、様々な新しい機能が追加されており、Kotlin/Native開発用に特に役立つものがいくつか含まれている。
- AutoCloseableインターフェイスのサポート
- Base64エンコーディングとデコーディングのサポート
- Kotlin/Nativeでの@Volatileのサポート
- Kotlin/Nativeの正規表現の使用時のスタックオーバーフローに対するバグフィックス
## AutoCloseableインターフェイスのサポート
::: note warn
新しいAutoCloseableインターフェイスは実験的であり、使うに```@OptIn(ExperimentalStdlibApi::class)```か、```-opt-in=kotlin.ExperimentalStdlibApi```コンパイラ引数でオプトインが必要である。
:::
```AutoCloseable```インターフェイスは、共通の標準ライブラリに追加されたので、リソースを閉じるためにすべてのライブラリ用に一つの共通インターフェイスを使うことができる。Kotlin/JVMでは```AutoCloseable```インターフェイスは```java.lang.AutoCoseable```のエイリアスである。
さらに拡張関数```use()```が現在は含まれており、それは例外が発生しようがしまいが、選択されたリソース上で与えられたブロック関数を実行した後で正しくリソースをクローズする。
標準の共通ライブラリに、```AutoCloseable```インターフェイスを実装する公開クラスは存在しない。以下の例では、```XMLWriter```インターフェイスを定義し、それを実装するリソースがあると仮定している。例えば、そのリソースはファイルを開き、XMLコンテンツを出力してそのあとでクローズするクラスであろう。
```Kotlin
interface XMLWriter : AutoCloseable {
    fun document(encoding: String, version: String, content: XMLWriter.() -> Unit)
    fun element(name: String, content: XMLWriter.() -> Unit)
    fun attribute(name: String, value: String)
    fun text(value: String)
}
fun writeBooksTo(writer: XMLWriter) {
    writer.use { xml ->
        xml.document(encoding = "UTF-8", version = "1.0") {
            element("bookstore") {
                element("book") {
                    attribute("category", "fiction")
                    element("title") { text("Harry Potter and the Prisoner of Azkaban") }
                    element("author") { text("J. K. Rowling") }
                    element("year") { text("1999") }
                    element("price") { text("29.99") }
                }
                element("book") {
                    attribute("category", "programming")
                    element("title") { text("Kotlin in Action") }
                    element("author") { text("Dmitry Jemerov") }
                    element("author") { text("Svetlana Isakova") }
                    element("year") { text("2017") }
                    element("price") { text("25.19") }
                }
            }
        }
    }
}
```
## Base64エンコーディングのサポート
Base64エンコーディングとデコーディングのサポートが追加された。3つのclassインスタンスが提供されており、それぞれ異なるエンコーディングスキームを使い、異なる振る舞いを示す。標準の[Base64エンコーディングスキーム](https://www.rfc-editor.org/rfc/rfc4648#section-4)用に、```Base64.Default```インスタンスを使うこと。
[URLとファイル名セーフな](https://www.rfc-editor.org/rfc/rfc4648#section-5)エンコーディングスキーム用に、```Base64.UrlSafe```インスタンスを使うこと。
[MIME](https://www.rfc-editor.org/rfc/rfc2045#section-6.8)エンコーディングスキーム用には、```Base64.Mime```インスタンスを使うこと。```Base64.Mime```インスタンスを使う場合、すべてのエンコーディング関数は、76文字で改行を挿入する。デコーディングの場合、不正な文字はスキップし、例外をスローしない。

::: note 
```Base64.Default```インスタンスは```Base64```クラスのcompanion objectである。結果として、```Base64.Default.encode()```と```Base64.Default.decode()```の代わりに、```Base64.encode()```と```Base64.decode()```経由でその関数を呼び出すことができる。
:::

```Kotlin
val foBytes = "fo".map { it.code.toByte() }.toByteArray()
Base64.Default.encode(foBytes) // "Zm8="
// あるいは:
// Base64.encode(foBytes)

val foobarBytes = "foobar".map { it.code.toByte() }.toByteArray()
Base64.UrlSafe.encode(foobarBytes) // "Zm9vYmFy"

Base64.Default.decode("Zm8=") // foBytes
// あるいは:
// Base64.decode(foBytes)

Base64.UrlSafe.decode("Zm9vYmFy") // foobarBytes
```
エンコード結果に、提供された```Appendable```型オブジェクトを追加するのと同様に、既存のバッファにbyteをエンコードあるいはデコードするために、追加の関数を使うことができる。
Kotlin/JVMでは、入力と出力ストリームでBase64エンコーディングとデコーディングを実行できるように、```encodingWith()```と```decodingWith()```拡張関数も追加されている。
## Kotlin/Nativeでの@Volatileのサポート
::: note warn
Kotlin/Nativeでの@Volatileは実験的である。いつでも削除あるいは変更される可能性がある。オプトインが必要(以下参照)である。評価目的のためにのみ使用すること。[YouTrack](https://kotl.in/issue)上でご意見をお聞かせください。
:::
```var```プロパティを```@Volatile```でアノテートする場合、このフィールドへのどんな読み書きもアトミックであり、書き込みは常に他のスレッドから参照可能であることを、バッキングフィールドがマークされる。
1.8.20より前は、[```kotlin.jvm.Volatile```アノテーション](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm/-volatile/)が、共通の標準ライブラリで利用可能なだけだった。しかし、このアノテーションはJVMでのみ有効である。Kotlin/Nativeで使う場合、無視され、エラーをもたらすことがありうる。
1.8.20では、共通のアノテーション```kotlin.concurrent.Volatile```が導入され、JVMとKotlin/Native両方で使うことができる。
### 有効化方法
この機能を試すには、```@OptIn(ExperimentalStdlibApi)```でオプトインし、```language-version 1.9```コンパイラオプションを有効にすること。Gradleプロジェクトで、build.gradle.ktsに以下を追加することで、可能になる。
```Kotlin
tasks
    .withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask<*>>()
    .configureEach {
        compilerOptions
            .languageVersion
            .set(
                org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9
            )
    }
```
## Kotlin/Nativeの正規表現の使用時のスタックオーバーフローに対するバグフィックス
Kotlinの以前のバージョンで、正規表現パターンが非常に単純でも、正規表現の入力が大量の文字を含む場合、クラッシュが起こることがあった。1.8.20ではこの問題は解決された。詳しくは[KT-46211](https://youtrack.jetbrains.com/issue/KT-46211?_ga=2.243750085.1572773554.1681091178-1843946880.1681091178&_gl=1*cr8tco*_ga*MTg0Mzk0Njg4MC4xNjgxMDkxMTc4*_ga_9J976DJZ68*MTY4MTEwMDk4Ny4yLjAuMTY4MTEwMDk5My41NC4wLjA.)を参照のこと。
# Serializationの更新
Kotlin 1.8.20では[Kotlin K2コンパイラのAlphaサポート](https://kotlinlang.org/docs/whatsnew1820.html#prototype-serialization-compiler-plugin-for-kotlin-k2-compiler)と、[companion object経由でのシリアライザのカスタマイズの禁止](https://kotlinlang.org/docs/whatsnew1820.html#prohibit-implicit-serializer-customization-via-companion-object)がもたらされている。
## Kotlin K2コンパイラのためのプロトタイプのシリアライゼーションコンパイラプラグイン
::: note warn
K2用のシリアライゼーションコンパイラプラグインのサポートは[Alpha](https://kotlinlang.org/docs/components-stability.html#stability-levels-explained)である。使うには[Kotlin K2コンパイラを有効にすること]。(https://kotlinlang.org/docs/whatsnew1820.html#how-to-enable-the-kotlin-k2-compiler)
:::

1.8.20から、シリアライゼーションコンパイラプラグインはKotlin K2コンパイラと動作する。試して、[ご意見をお聞かせください](https://kotlinlang.org/docs/whatsnew1820.html#leave-your-feedback-on-the-new-k2-compiler)。
## companion object経由での暗黙のシリアライザーのカスタマイズの禁止
現在、クラスを```@Serializable```でシリアライズ可能に宣言することができ、同時にそのcompanion object上で、@Serializerアノテーションをつけることでカスタムシリアライザーを宣言することができる。
例：
```Kotlin
import kotlinx.serialization.*


@Serializable
class Foo(val a: Int) {
   @Serializer(Foo::class)
   companion object {
       // KSerializer<Foo>のカスタマイズ実装
   }
}
```
この場合、```@Serializable```アノテーションから、どのシリアライザーが使われるのか、明確でない。実際は、```Foo```クラスはカスタムシリアライザーを持っている。
この種の混乱を避けるため、Kotlin 1.8.20では、このシナリオが検出されるとコンパイラ警告が導入された。その警告は、この問題を解決するために可能な移行パスを含んでいる。
コードでそのような構成物を使う場合、次のように更新することを推奨している。
```Kotlin
import kotlinx.serialization.*


@Serializable(Foo.Companion::class)
class Foo(val a: Int) {
   // @Serializer(Foo::class)を使うかどうかということは関係ない
   companion object: KSerializer<Foo> {
       // KSerializer<Foo>のカスタマイズ実装
   }
}
```
このアプローチでは、Fooクラスがcompanionオブジェクトでカスタムシリアライザーを使うことが明確である。詳しくは[YouTrackチケット](https://youtrack.jetbrains.com/issue/KT-54441?_ga=2.256268235.1572773554.1681091178-1843946880.1681091178&_gl=1*c2l6rj*_ga*MTg0Mzk0Njg4MC4xNjgxMDkxMTc4*_ga_9J976DJZ68*MTY4MTEwMDk4Ny4yLjAuMTY4MTEwMDk5My41NC4wLjA.)を参照のこと。
# ドキュメントの更新
Kotlinドキュメンテーションでは、いくつかの注目に値する変更がある。
- [SpringBootとKotlin入門](https://kotlinlang.org/docs/jvm-get-started-spring-boot.html) - データベースを使う簡単なアプリケーションを作り、SpringBootとKotlinの機能について知識を深める
- [スコープ関数](https://kotlinlang.org/docs/scope-functions.html) - 標準ライブラリから有益なスコープ関数を使い、コードをシンプルにする方法を学ぶ
- [Cocoa pod統合](https://kotlinlang.org/docs/native-cocoapods.html) - CocoaPodと連携する環境をセットアップする

# Kotlin 1.8.20のインストール
## IDEバージョンのチェック
[IntelliJ IDEA](https://www.jetbrains.com/idea/download/)2022.2と2022.3では、Kotlinプラグインをバージョン1.8.20への更新を自動で提案される。IntelliJ IDEA 2023.1ではKotlin 1.8.20が組み込まれている。
Android Studio Flamingo(222)とGiraffe(223)は次のリリースでKotlin 1.8.20をサポートする予定である。
新しいコマンドラインコンパイラは、[GitHubリリースページ](https://github.com/JetBrains/kotlin/releases/tag/v1.8.20)でダウンロード可能である。
## Gradle設定の構成
Kotlin成果物と依存性を正しくダウンロードするため、```settting.gradle.kts```ファイルを更新し、Maven Centralリポジトリを使うこと。
```Kotlin
pluginManagement {
    repositories {
        mavenCentral()
        gradlePluginPortal()
    }
}
```
リポジトリが指定されていない場合、Gradleは衰退しつつあるJCenterリポジトリを使い、Kotlin成果物で問題を引き落とすことがありうる。