6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Kotlin 1.8.20の変更点

Posted at

ソース記事
※Kotlin/JS、Kotlin/Nativeについては割愛します。
リリース日:2023/4/3
Kotlin 1.8.20のリリースが公開され、こちらに最大のハイライトのいくつかがある。

  • 新しいKotlin K2コンパイラの更新
  • 新しい実験的Kotlin/Wasmターゲット
  • Gradleでの新しいJVMの増分コンパイルがデフォルト化
  • Kotlin/Nativeターゲットの更新
  • Kotlin MultiplatformにおけるGradle複合ビルドのプレビュー
  • XcodeにおけるGradleエラー出力の改善
  • 標準ライブラリにおけるAutoCloseableインターフェイスの実験的サポート
  • 標準ライブラリにおけるBase64エンコーディングの実験的サポート
    こちらの映像で、変更点の短い概要をみつけることができる。

IDEのサポート

1.8.20をサポートするKotlinプラグインは以下。

IDE サポートバージョン
IntelliJ IDEA 2022.2.x, 2022.3.x, 2023.1.x
Android Studio Flamingo (222)

Kotlin成果物と依存関係を適切にダウンロードするためには、Maven Centralリポジトリを使うためにGradle設定を行うこと

新しいKotlin K2コンパイラの変更点

KotlinチームはK2コンパイラの安定化を継続している。Kotlin 1.7.0のアナウンスで述べたように、まだAlphaである。このリリースではK2 Betaへの道におけるさらなる改善が導入されている。
この1.8.20リリースからKotlin K2コンパイラでは、以下が行われている。

Kotlin K2コンパイラの有効化方法

Kotlin K2コンパイラを有効化し、テストするためには、次のコンパイラオプションで新しい言語バージョンを使う。

-language-version 2.0

build.gradle(.kts)ファイルで、指定することができる。

kotlin {
   sourceSets.all {
       languageSettings {
           languageVersion = "2.0"
       }
   }
}

以前の-Xuse-k2コンパイラオプションは非推奨になった。

新しいKotlin K2コンパイラのAlphaバージョンは、JVMとJS IRプロジェクトでのみ動作する。Kotlin/Nativeやマルチプラットフォームプロジェクトはサポートされていない。

新しいK2コンパイラにおけるフィードバック

是非ご意見をお聞かせください!

言語

Kotlinが進化し続けるように、我々は1.8.20で新しい言語機能のためのプレビューバージョンを導入している。

  • Enumクラス値関数のモダンで高性能な代替
  • dataクラスと調和するためのdataオブジェクトのプレビュー
  • インラインクラスでの本体を持つセカンダリコンストラクタの制限の撤廃

Enumクラス値関数のモダンで高性能な代替

この機能は実験的である。いつでも削除あるいは変更される可能性がある。オプトインが必要(以下参照)である。評価目的のためにのみ使用すること。YouTrack上でご意見をお聞かせください。

Enumクラスは合成values()関数を持ち、定義されたenum定数の配列を返却する。しかし、配列を使うことはKotlinとJavaでに隠れた性能問題を引き起こすことがある。さらにほとんどのAPIはコレクションを使い、最終的に変換が必要である。これらの問題を修正するため、Enumクラスのためのentriesプロパティを導入し、values()関数の代わりに使うべきとした。呼び出し時に、entriesプロパティは、事前割り当てされた定義されたenum定数の変更できないリストを返却する。

values()関数は引き続きサポートされるが、entriesプロパティを代わりに使用することを推奨する。

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に以下を追加することで可能となる。

tasks
    .withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask<*>>()
    .configureEach {
        compilerOptions
            .languageVersion
            .set(
                org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9
            )
    }

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

この提案の詳細は、KEEP noteを参照のこと。

data classと調和するためのdata objectのプレビュー

data objectはシングルトンの意味と簡潔なtoString()表現を持つobjectを宣言することが可能になる。このスニペットでは、object宣言にdataキーワードを追加することで、toString()出力の可読性を向上することがわかる。

package org.example
object MyObject
data object MyDataObject

fun main() {
    println(MyObject) // org.example.MyObject@1f32e575
    println(MyDataObject) // MyDataObject
}

特に(sealedクラスsealedインターフェイス階層のような)sealed階層には、data objectdata class宣言と便利に並んで使うことができるため、ぴったりフィットする。このスニペットでは、プレーンなobjectの代わりにdataオブジェクトとして、EndOfFileを宣言することで、手動でオーバーライドする必要なく、美しいtoStringを得ることができる。これは付属のdata class宣言との調和を維持する。

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での最初のプレビューバージョンから、data objectの意味合いが改良された。今ではコンパイラによって、多くの便利な関数が生成される。

toString

data objectのtoString()関数はオブジェクトの単純な名前を返却する。

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の複数のインスタンスが存在するときに落とし穴を避けることができる。以下のスニペットでこの特定のエッジケースを例示する。

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 objectdata class宣言は度々一緒に使用し、いくつか類似点を持つ一方で、いくつかの関数はdata objectには生成されない。
data object宣言はシングルトンオブジェクトとして使うことを意図しているため、copy()関数は生成されない。シングルトンパターンはクラスのインスタンス化を単一のインスタンスに制限するので、インスタンスのコピー作成を許可することは、その制限に違反するだろう。
また、data classと異なり、data objectはdataプロパティを一つも持たない。そのようなオブジェクトを分解しようとすることは意味がないため、componentN()関数は生成されない。
YouTrackでこの機能についてのご意見をお聞かせください。

data objectプレビューの有効化方法

この機能を試すには、-language-version 1.9コンパイラオプションを有効にすること。Gradleプロジェクトでは、build.gradle.ktsに以下を追加することで可能となる。

tasks
    .withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask<*>>()
    .configureEach {
        compilerOptions
            .languageVersion
            .set(
                org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9
            )
    }

インラインクラスでの本体を持つセカンダリコンストラクタの制限の撤廃

この機能は実験的である。いつでも削除あるいは変更される可能性がある。オプトインが必要(以下参照)である。評価目的のためにのみ使用すること。YouTrack上でご意見をお聞かせください。

Kotlin 1.8.20では、インラインクラスでの本体を持つセカンダリコンストラクタの使用制限が撤廃されている。
インラインクラスは、initブロックの無いpublicプライマリコンストラクタあるいはセカンダリコンストラクタのみが、明確な初期化の意味合いを持つことをかつて許可されていた。結果として根底にある値をカプセル化することや制約のある値を表すインラインクラスを作ることが不可能だった。
これらの問題はKotlin 1.4.30がinitブロックの制限を撤廃することで修正された。現在は一歩進め、プレビューモードで本体を持つセカンダリコンストラクタを許可している。

@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に以下を追加することで可能となる。

tasks
    .withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask<*>>()
    .configureEach {
        compilerOptions
            .languageVersion
            .set(
                org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9
            )
    }

この機能を試し、YouTrackですべての報告を提出することをお勧めする。そうすればKotlin1.9.0でデフォルトにすることができる。
Kotlinのinclineクラスの開発について詳しくはこのKEEPをご覧ください。

新しいKotlin/WASMターゲット

Kotlin/Wasm (Kotlin WebAssembly)はこのプレビューリリースで実験的になっている。KotlinチームはWebAssemblyが将来性のある技術であることを見出し、それを使い、Kotlinのすべての利点を得るためのより良い方法を見つけたいと思っている。
WebAssemblyバイナリフォーマットは自身のVMで動作するため、プラットフォーム独立である。ほぼすべてのブラウザはWebAssemblly 1.0をすでにサポートしている。WebAssembllyを実行するための環境をセットアップするには、Kotlin/WASMがターゲットとする実験的ガベージコレクションモードを有効にする必要があるだけである。詳細な手順はこちらで見つけることができる。Kotlin/WASMの有効化方法
新しいKotlin/WASMターゲットの次の利点を強調したい。

  • Kotlin/WASMはLLVMを使用しないため、wasm32 Kotlin/Nativeターゲットに比べて、より高速なコンパイル。
  • Wasmガベージコレクションのおかげで、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映像でご覧ください。

Kotlin/WASMの有効化方法

Kotlin/WASMを有効化し試すには、build.gradle.ktsファイルを更新すること。

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
    }
}

Kotlin/WASMのサンプルGitHubリポジトリをチェックしてください。

Kotlin/WASMプロジェクトを実行するには、対象の環境設定を更新する必要がある。

Chrome

  • バージョン109用
    --js-flags=--experimental-wasm-gcコマンドライン引数でアプリケーションを実行する。
  • バージョン110以上用
    1. ブラウザで、chrome://flags/#enable-webassembly-garbage-collectionに遷移する
    2. WebAssembly Garbage Collectionを有効にする
    3. ブラウザを再起動する

Firefox

  • バージョン109以上用
    1. ブラウザで、about:configに遷移する
    2. javascript.options.wasm_function_referencesjavascript.options.wasm_gcを有効にする
    3. ブラウザを再起動する

Edge

  • バージョン109以上用
    --js-flags=--experimental-wasm-gcコマンドライン引数でアプリケーションを実行する。

Kotlin/WASMにおけるフィードバック

是非ご意見をお聞かせください!

Kotlin/JVM

Kotlin 1.8.20では、Javaの合成プロパティ参照のプレビューと、kaptスタブ生成タスクのJVM IRバックエンドのデフォルトサポートが導入されている。

Javaの合成プロパティ参照のプレビュー

この機能は実験的である。いつでも削除あるいは変更される可能性がある。評価目的のためにのみ使用すること。YouTrack上でご意見をお聞かせください。

Kotlin 1.8.20では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::ageperson::ageへの参照を作ることもできる。nameに対してもまったく同様に動作する。

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に以下を追加することで可能となる。

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バックエンドのサポートが導入された。今回のリリースから、このサポートはデフォルトで動作する。もはやそれを有効化するために、gradle.propertieskapt.use.jvm.ir=trueを指定する必要は無い。この機能についてYouTrack上でご意見をお聞かせください。

Gradle

Kotlin 1.8.20はいくつかのMultiplatformプラグインでの特別なケースを除いてGradle 6.8から7.6までと完全に互換性がある。最新のGradleリリースまでGradleバージョンを上げて使うこともできるが、その場合、非推奨警告に直面するか、いくつかの新しいGradle機能が動作しない可能性があることに注意すること。
このバージョンでは以下の変更がもたらされている。

  • Gradleプラグインのバージョンの新しい統一
  • Gradleでの新しいJVM差分コンパイルのデフォルト化
  • コンパイルタスクの出力の正確なバックアップ
  • 全Gradleバージョン用の遅延Kotlin/JVMタスク生成
  • コンパイルタスクの宛先ディレクトリのデフォルト以外の場所
  • HTTP統計サービスへコンパイル引数を報告回避する機能

Gradleプラグインのバージョンの新しい統一

Gradleは共に動作しなければならない依存性が常にバージョンが統一されていることを保証する方法を提供している。Kotlin 1.8.20でもこのアプローチを採用した。それはデフォルトで動作し、有効にするために構成を変更したり、更新する必要はない。さらにKotlin Gradleプラグインの推移的依存性を解決するための回避策に頼る必要はもう無い。
この機能についてYouTrackでご意見をお聞かせください。

Gradleでの新しいJVM差分コンパイルのデフォルト化

差分コンパイルの新しアプローチは、Kotlin 1.7.0から利用可能であったが、現在ではデフォルトで動作する。有効にするためにgradle.propertieskotlin.incremental.useClasspathSnapshot=trueを指定する必要はもう無い。
このことについてご意見をお聞かせください。YouTrackで問題を報告することができる。

コンパイルタスクの出力の正確なバックアップ

コンパイルタスクの出力の正確なバックアップは実験的である。使うには、gradle.propertieskotlin.compiler.preciseCompilationResultsBackup=trueを追加すること。YouTrackでご意見をお聞かせください。

Kotlin 1.8.20から、正確なバックアップを有効にすることができ、それによって、Kotlinが差分コンパイルでリコンパイルするクラス群のみが、バックアップされるようになる。フルおよび正確なバックアップにより、コンパイルエラーの後で再度差分的にビルドを実行することができる。正確なバックアップは、フルバックアップに比べてビルド時間も節約する。フルバックアップは巨大なプロジェクト、あるいは多くのタスクがバックアップを行っている場合、あるいはプロジェクトが遅いHDDに配置されている場合特に、著しく時間がかかるかもしれない。
この最適化は実験的である。gradle.propertiesファイルにkotlin.compiler.preciseCompilationResultsBackupGradleプロパティを追加することで有効にすることができる。

kotlin.compiler.preciseCompilationResultsBackup=true

こちらに、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バリアントを使い、Kotlin2JsCompileタスクのdestinationDirectoryを上書きすること

JARファイル内のsourceSets.main.outputssourceSets.main.kotlin.classesDirectoriesを明示的に追加する必要がある。
tasks.jar(type: Jar) { from sourceSets.main.outputs from sourceSets.main.kotlin.classesDirectories }

HTTP統計サービスへコンパイル引数を報告回避する機能

現在、Kotlin Gradleプラグインが、HTTPビルドレポートにコンパイル引数を含むべきかを制御することができるようになった。時々、プラグインがこれらの引数を報告する必要が無いかもしれない。プロジェクトが多くのモジュールを含む場合、レポート内のコンパイル引数が非常に重くなり、役立たないことがありうる。現在は、それを無効にする方法があり、それによりメモリを節約する。gradle.propertiesあるいはlocal.propertiesで、kotlin.build.report.include_compiler_arguments=(true|false)を使うこと。
YouTrackでこの機能について、ご意見をお聞かせください。

標準ライブラリ

Kotlin 1.8.20では、様々な新しい機能が追加されており、Kotlin/Native開発用に特に役立つものがいくつか含まれている。

  • AutoCloseableインターフェイスのサポート
  • Base64エンコーディングとデコーディングのサポート
  • Kotlin/Nativeでの@Volatileのサポート
  • Kotlin/Nativeの正規表現の使用時のスタックオーバーフローに対するバグフィックス

AutoCloseableインターフェイスのサポート

新しいAutoCloseableインターフェイスは実験的であり、使うに@OptIn(ExperimentalStdlibApi::class)か、-opt-in=kotlin.ExperimentalStdlibApiコンパイラ引数でオプトインが必要である。

AutoCloseableインターフェイスは、共通の標準ライブラリに追加されたので、リソースを閉じるためにすべてのライブラリ用に一つの共通インターフェイスを使うことができる。Kotlin/JVMではAutoCloseableインターフェイスはjava.lang.AutoCoseableのエイリアスである。
さらに拡張関数use()が現在は含まれており、それは例外が発生しようがしまいが、選択されたリソース上で与えられたブロック関数を実行した後で正しくリソースをクローズする。
標準の共通ライブラリに、AutoCloseableインターフェイスを実装する公開クラスは存在しない。以下の例では、XMLWriterインターフェイスを定義し、それを実装するリソースがあると仮定している。例えば、そのリソースはファイルを開き、XMLコンテンツを出力してそのあとでクローズするクラスであろう。

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エンコーディングスキーム用に、Base64.Defaultインスタンスを使うこと。
URLとファイル名セーフなエンコーディングスキーム用に、Base64.UrlSafeインスタンスを使うこと。
MIMEエンコーディングスキーム用には、Base64.Mimeインスタンスを使うこと。Base64.Mimeインスタンスを使う場合、すべてのエンコーディング関数は、76文字で改行を挿入する。デコーディングの場合、不正な文字はスキップし、例外をスローしない。

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

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のサポート

Kotlin/Nativeでの@Volatileは実験的である。いつでも削除あるいは変更される可能性がある。オプトインが必要(以下参照)である。評価目的のためにのみ使用すること。YouTrack上でご意見をお聞かせください。

varプロパティを@Volatileでアノテートする場合、このフィールドへのどんな読み書きもアトミックであり、書き込みは常に他のスレッドから参照可能であることを、バッキングフィールドがマークされる。
1.8.20より前は、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に以下を追加することで、可能になる。

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を参照のこと。

Serializationの更新

Kotlin 1.8.20ではKotlin K2コンパイラのAlphaサポートと、companion object経由でのシリアライザのカスタマイズの禁止がもたらされている。

Kotlin K2コンパイラのためのプロトタイプのシリアライゼーションコンパイラプラグイン

K2用のシリアライゼーションコンパイラプラグインのサポートはAlphaである。使うには[Kotlin K2コンパイラを有効にすること]。(https://kotlinlang.org/docs/whatsnew1820.html#how-to-enable-the-kotlin-k2-compiler)

1.8.20から、シリアライゼーションコンパイラプラグインはKotlin K2コンパイラと動作する。試して、ご意見をお聞かせください

companion object経由での暗黙のシリアライザーのカスタマイズの禁止

現在、クラスを@Serializableでシリアライズ可能に宣言することができ、同時にそのcompanion object上で、@Serializerアノテーションをつけることでカスタムシリアライザーを宣言することができる。
例:

import kotlinx.serialization.*


@Serializable
class Foo(val a: Int) {
   @Serializer(Foo::class)
   companion object {
       // KSerializer<Foo>のカスタマイズ実装
   }
}

この場合、@Serializableアノテーションから、どのシリアライザーが使われるのか、明確でない。実際は、Fooクラスはカスタムシリアライザーを持っている。
この種の混乱を避けるため、Kotlin 1.8.20では、このシナリオが検出されるとコンパイラ警告が導入された。その警告は、この問題を解決するために可能な移行パスを含んでいる。
コードでそのような構成物を使う場合、次のように更新することを推奨している。

import kotlinx.serialization.*


@Serializable(Foo.Companion::class)
class Foo(val a: Int) {
   // @Serializer(Foo::class)を使うかどうかということは関係ない
   companion object: KSerializer<Foo> {
       // KSerializer<Foo>のカスタマイズ実装
   }
}

このアプローチでは、Fooクラスがcompanionオブジェクトでカスタムシリアライザーを使うことが明確である。詳しくはYouTrackチケットを参照のこと。

ドキュメントの更新

Kotlinドキュメンテーションでは、いくつかの注目に値する変更がある。

  • SpringBootとKotlin入門 - データベースを使う簡単なアプリケーションを作り、SpringBootとKotlinの機能について知識を深める
  • スコープ関数 - 標準ライブラリから有益なスコープ関数を使い、コードをシンプルにする方法を学ぶ
  • Cocoa pod統合 - CocoaPodと連携する環境をセットアップする

Kotlin 1.8.20のインストール

IDEバージョンのチェック

IntelliJ IDEA2022.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リリースページでダウンロード可能である。

Gradle設定の構成

Kotlin成果物と依存性を正しくダウンロードするため、settting.gradle.ktsファイルを更新し、Maven Centralリポジトリを使うこと。

pluginManagement {
    repositories {
        mavenCentral()
        gradlePluginPortal()
    }
}

リポジトリが指定されていない場合、Gradleは衰退しつつあるJCenterリポジトリを使い、Kotlin成果物で問題を引き落とすことがありうる。

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?