Kotlin 2.5.0-Beta2を2.4.21と比べて検証|名前で取り出す分解宣言と、戻り値を使わない呼び出しへの警告

Kotlin 2.5.0-Beta2が10月21日に公開、安定版2.4.21と並べて確かめた

JetBrainsが、2026年10月21日にKotlin 2.5.0-Beta2を公開しました。Kotlinは、Androidアプリの標準的な開発言語で、サーバーやiOSと共通のコードを書くKotlin Multiplatformにも使われています。次の大きな版である2.5.0の2回目のベータ版で、新機能は公式ドキュメントの「What's new」にまとまっています。

今回の変更には、既存のコードの書き方や警告の数に関わるものが含まれます。データクラスの中身を名前で取り出す書き方が使えるようになり、戻り値を使わない呼び出しには標準で警告が出ます。中身が同じなら等しいとみなす新しい「値クラス」や、標準ライブラリの新しい関数も、オプションを付けると試せます。

この記事では、最新の安定版2.4.21と2.5.0-Beta2のコンパイラーを同じMacに入れ、同じコードをコンパイルして実行した結果を並べます。2.5へ上げたときにビルドがどう変わるかと、新機能を試す方法を確かめました。

Kotlin 2.5.0-Beta2の要点

名前で取り出す書き方が標準になり、使わない戻り値に警告が出る

オプションなしで使える

(val age, val name) = user

プロパティ名で取り出すので、並び順を取り違えない。

ビルドに影響

使わない戻り値に警告

警告をエラーとして扱う設定では、ビルドが止まる。

オプションを付けて試せる

値クラスと新しい関数

複数のプロパティを持つ値クラス、型の違う比較の警告、onTrueなど。

同じコードをコンパイルした結果(2026年10月25日、macOS 27.0.1、JDK 21)
確かめたコードKotlin 2.4.21Kotlin 2.5.0-Beta2
名前で取り出す分解エラー(2.5から)オプションなしで動く
戻り値を使わないsorted()など警告なし警告(-Werrorではビルド失敗)
複数のプロパティを持つvalue class本番向けでない内部用オプションでのみ動く-Xfull-value-classesで動く
型の違うdata class同士の==警告なしオプションを付けると警告
onTrue / onFalse / ifOrNull関数が見つからないエラー@OptInで動く

データクラスの中身を、並び順ではなく名前で取り出せる

Kotlinには、データクラスの中身をval (a, b) = userのように1行で取り出す「分解宣言」があります。この書き方は、左辺の変数名と関係なく、クラスで宣言した順番どおりに値を割り当てます。変数名を書き間違えても、型が合えばそのまま動きます。

data class User(val name: String, val age: Int)

fun main() {
    val user = User("Ken", 30)
    val (age, name) = user
    println("age=$age name=$name")   // age=Ken name=30
}

2.4.21でも2.5.0-Beta2でも、このコードはエラーも警告もなくage=Ken name=30と表示しました。変数ageには1番目のプロパティnameの値が入っています。

2.5では、括弧の中にvalを書く(val age, val name) = userという形で、プロパティ名に合わせて取り出せます。公式ドキュメントでは、この名前による分解が安定した機能として標準で有効になったと説明しています。

data class User(val name: String, val age: Int)

fun main() {
    val user = User("Ken", 30)
    (val age, val name) = user
    println("$name $age")   // Ken 30
}

// Kotlin 2.4.21
destruct.kt:5:6: error: the feature "name based destructuring" is only available since language version 2.5

2.5.0-Beta2はオプションなしでコンパイルし、Ken 30と正しく表示しました。2.4.21では「2.5から使える機能」というエラーになります。従来のval (a, b)は2.5でも並び順のまま動くため、既存のコードを書き換える必要はありません。プロパティの多いクラスや、あとで並び順が変わりそうなクラスから、名前で取り出す形に切り替えると取り違えを防げます。

戻り値を使わない呼び出しに、標準で警告が出る

2.5では、戻り値を使わずに捨てている呼び出しを見つける機能が、標準で有効になりました。よくある例は、リストを並べ替えるsorted()です。sorted()は並べ替えた新しいリストを返すだけで、元のリストは変わりません。

fun main() {
    val names = listOf("b", "a")
    names.sorted()
    "kotlin".uppercase()
    println(names)   // [b, a]
}

// Kotlin 2.5.0-Beta2
unused.kt:3:11: warning: unused return value of 'sorted'.
unused.kt:4:14: warning: unused return value of 'uppercase'.

2.4.21は何も言わずにコンパイルし、実行結果は並べ替わっていない[b, a]でした。2.5.0-Beta2は同じコードの2か所に警告を出しました。並べ替えたつもりで結果を受け取っていない、という見つけにくい誤りを、コンパイルの段階で拾えます。

Kotlin 2.4.21 + -Werror

警告が出ないため、そのままコンパイルが成功する。

Kotlin 2.5.0-Beta2 + -Werror

「warnings found and -Werror specified」でコンパイルが止まる。

警告をエラーとして扱う設定(コマンドラインの-Werror、GradleのallWarningsAsErrors)を使っているプロジェクトでは、2.5へ上げると、この警告が出た箇所でビルドが止まります。上げる前に2.5.0-Beta2で一度コンパイルし、警告の出た箇所で戻り値を使うか、不要な呼び出しを消しておくと、正式版へ切り替えた日にビルドが止まらずに済みます。

中身が同じなら等しい「値クラス」を、オプションで試せる

Kotlinのvalue classは、これまでプロパティを1つだけ持つ軽量なクラスとして使われてきました。2.5では、複数のプロパティを持ち、中身が同じなら同じものとして扱う「完全な値クラス」を、実験的な機能として試せます。

value class Complex(val real: Double, val imaginary: Double)

val a = Complex(1.0, 2.0)
val b = Complex(1.0, 2.0)
println(a)                               // Complex(real=1.0, imaginary=2.0)
println(a == b)                          // true
println(a.hashCode() == b.hashCode())    // true

2.5.0-Beta2に-Xfull-value-classesを付けると、このコード(val a以降はmain関数の中に書いたもの)はコンパイルでき、toString()、equals()、hashCode()が自動で作られていることを確かめられました。2.4.21では、内部用の-XXLanguage:+FullValueClassesを付けると同じ結果になりますが、コンパイラーが「本番では使わないこと」という注意を表示します。2.5では、通常の実験的なオプションとして試せるようになっています。

公式ドキュメントによると、完全な値クラスには、プロパティを位置で取り出すcomponent1()などの関数や、copy()がまだありません。中身を取り出すときは、前の節の名前による分解を使います。また、今のプロパティが1つのvalue class(中身をそのまま埋め込む「インライン」の値クラス)は、今後inline修飾子か@JvmInlineで明示する形へ移る予定です。公式ドキュメントでは、2.5.20から、どちらの印も付けていない値クラスに警告を出し、2.6.0か2.7.0でエラーにする計画が示されています。Androidでよく使う@JvmInline value classの書き方は、すでに印を付けた形にあたります。

型の違うデータクラスの比較と、Booleanの新しい関数

ほかにも、オプションを付けて試せる機能があります。1つは、構造の似た別のデータクラス同士を==で比べたときの警告です。

data class Point(val x: Double, val y: Double)
data class Vector(val x: Double, val y: Double)

fun isOrigin(v: Vector): Boolean = v == Point(0.0, 0.0)

// Kotlin 2.5.0-Beta2 + -Xstrict-equality-for-structural-classes
strict.kt:4:36: warning: comparison is always unsuccessful because 'Vector' and 'Point' are incompatible types with structural equality.

Vector(0.0, 0.0)を渡しても結果はfalseです。2.4.21では警告が出ず、2.5.0-Beta2でもオプションを付けたときだけ警告が出ました。

もう1つは、標準ライブラリに加わったonTrue、onFalse、ifOrNullです。@OptIn(ExperimentalStdlibApi::class)を付けると使えます。次のコードは、@OptInを付けたmain関数の中身です。

val tags = mutableSetOf("kotlin", "jvm")
val added = tags.add("wasm").onTrue { println("Tag added") }
val removed = tags.remove("native").onFalse { println("Tag not found") }
val message = ifOrNull("wasm" in tags) { "Wasm tag is available" }

2.5.0-Beta2では、追加に成功したときだけ「Tag added」、削除する要素がなかったときだけ「Tag not found」が表示され、messageには文字列が入りました。2.4.21では3つとも関数が見つからないエラーです。

公式ドキュメントで2.5の新機能として紹介されているcompanionブロックとcompanion拡張(companion { }の中に書いたプロパティをVector.Zeroのように呼べる書き方)も試しました。2.5.0-Beta2で必要なオプション-Xcompanion-blocks-and-extensionsを2.4.21に付けても、公式の例は同じ結果で動きました。オプションなしでは、どちらの版でもエラーになります。安定版の2.4.21でも、同じオプションを付ければこの機能を試せます。

2.5.0-Beta2を試すときに確かめる3つのこと

ベータ版のため、公開中のアプリのビルドは2.4系のままにして、作業用のブランチで試す手順を勧めます。公式ドキュメントによると、IntelliJ IDEAかAndroid Studioを最新にしたうえで、ビルドスクリプトのKotlinの版を2.5.0-Beta2に替えます。

  1. 1. コンパイラーを動かすJDKを17以上にする

    2.5ではJDK 8〜16でコンパイラーを動かすとエラーになる。CIのJDKの版も確かめる。

  2. 2. 戻り値の警告の数を数える

    allWarningsAsErrorsを使っているなら、2.5でビルドが止まる箇所を先に直す。

  3. 3. Kotlin Multiplatformの設定を見直す

    Swift exportを使っている場合は、設定の書き方がswiftExport { }からexport { swift { } }へ変わる。

公式ドキュメントは、このほかに型推論の最適化で、まれに推論される型やエラーの出方が変わる場合があると説明しています。名前による分解と戻り値の警告は、オプションなしで動くため、手元のプロジェクトで2.5.0-Beta2にしてコンパイルするだけで、影響を受ける箇所の数がつかめます。