What's new in Kotlin 1.8.20
一言で表すと
概要
Language
A modern and performant replacement of the Enum class values function
Enumのメンバの一覧を取得するvalues()はパフォーマンスが悪い問題があったので、新たにentriesが追加された
language-version 1.9にしてExperimentalStdlibApiを付ける必要がある
values()はarrayであり、mutableになっている
予期せぬ変更を防止するため、values()は毎回インスタンス生成しており、パフォーマンス上の問題を引き起こす
entrisはimmutableなEnumEntriesを返す
sealed interface EnumEntries<E : Enum<E>> : List<E>
chigichan24.icon Listの継承なんだね :eyes:
ListであるのはEnumのメンバ一覧であることがわかりやすくするためと、今後の拡張性を増やすため
後方互換性
以下のようなコードがすでに存在していると、重複して曖昧になる
code:kotlin
enum class MyEnum {
A;
companion object {
val entries: Any? = ...
}
}
普通なら言語のキーワードが優先されるが、Kotlin 2.1まで例外的に以前アクセスできたほうが優先される
Mori Atsushi.icon こういう互換性考えるの大変そう
chigichan24.icon entriesあるかな...
data object
sealed class等でdata classとobjectを並列に扱いたい時に便利
toString()でハッシュ値を含まないクラス名が取得できる
equalsとhashCodeがリフレクション等でインスタンス生成したときも同一になる
リフレクションでobjectインスタンスを作成するとequalsがfalse
これIntentかなにかで渡す時にハマったことあるので助かる
inline classでボディーを持つセカンダリコンストラクタが許可
code:kotlin
@JvmInline
value class Person(private val fullName: String) {
// Allowed since Kotlin 1.4.30:
init {
check(fullName.isNotBlank()) {
"Full name shouldn't be empty"
}
}
// Preview available since Kotlin 1.8.20:
constructor(name: String, lastName: String) : this("$name $lastName") {
check(lastName.isNotBlank()) {
"Last name shouldn't be empty"
}
}
}
chigichan24.icon ふーん。これほしいか???
New Kotlin/Wasm target
Kotlin/WasmがこのリリースでExperimentalに
KotlinチームがハイライトするKotlin/Wasmの利点は次の通り
LLVMを使わないため、wasm32 に比べてコンパイル速度が早い
Wasm GCのおかげで、wasm32 にくらべてJSとの相互運用とブラウザとの統合がより容易に
chigichan24.icon wasm gc ってproposalの段階だと思っていた
Wasmはコンパクトでバイトコードが解析しやすいため、Kotlin/JSやJavaScriptと比較してアプリケーションの起動が高速になる可能性がある
Wasmは静的型付け言語のため、Kotlin/JSやJavaScriptと比較してアプリケーションのランタイムパフォーマンスが向上する
Kotlin/Wasm用の標準ライブラリ(stdlib)とテストライブラリ(kotlin.test)は提供されている
Mori Atsushi.icon Kojectもはやく対応したいのに…
IDEのサポートは将来のリリースで追加予定
mayamito.icon 早くして❤️
セットアップ
code: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
}
}
Chromeでの動かし方
バージョン109
コマンドライン引数 --js-flags=--experimental-wasm-gc をつけてブラウザを実行
バージョン110以降
chrome://flags/#enable-webassembly-garbage-collection を開く
WebAssembly Garbage Collection を有効にする
ブラウザを再起動する
Firefoxでの動かし方
バージョン109以降
about:config を開く
javascript.options.wasm_function_references と javascript.options.wasm_gc を有効にする
ブラウザを再起動する
Edgeでの動かし方
バージョン109以降
コマンドライン引数 --js-flags=--experimental-wasm-gc をつけてブラウザを実行
開発チーム: フィードバックお待ちしてます❤️
Update for Kotlin/Native target
1.8.20で以下をdeprecated にした。1.9.20で完全削除される
iosArm32 ... 32-bit iOS appは昔にdepreatedになったので
watchosX86...intel macの古いsimulator向けのもののため。watchosX64をつかってね
wasm32 ... Kotlin/Wasm toolchainにしたので、deprecated
mingwX86 ... 需要が低いため
linuxArm32Hfp ... しんどいらしい
linuxMips32 ... We haven’t seen any real demand for these two.
linuxMipsel32 ... We haven’t seen any real demand for these two.
どのターゲットのサポートを重点的に行うかについて3つのカテゴリ分け(Tier1 - Tier3)をすることにした。
たとえばiosArm64はKMMの文脈で大事なので優先度が高い
kotlinx.coroutinesを実装するときにどのターゲットから優先的にやるかみたいなのもこの階層わけに影響する。
Tier 1
targetはCIで定期的にテストしてコンパイルと実行結果が壊れないようにする。
ソースやバイナリ互換性を保持するように頑張る
例
linuxX64
macosX64
macosArm64
iosSimulatorArm64
iosX64
Tier2
targetはCIで定期的にテストしてコンパイルのみが壊れないようにする。
実行可能性については頻繁には見ない
ソースやバイナリ互換性を保持するように頑張る
例
linuxArm64
watchosSimulatorArm64
watchosX64
watchosArm32
watchosArm64
tvosSimulatorArm64
tvosX64
tvosArm64
iosArm64
これは Tier1 に持っていきたいけど、なんか大変らしい。今のところはiosSimulatorArm64に頼っている状況でこれで十分ではあると考えている
Tier3
targetはCIでのテストを保証しない
バイナリやソースの互換を保証しない。
例
androidNativeArm32
androidNativeArm64
androidNativeX86
androidNativeX64
mingwX64
watchosDeviceArm64
NDKとWindowsが捨てられている...
Preview of Gradle composite builds support in Kotlin Multiplatform
1.8.20-RC2からKotlin MultiplatformでGradleのcomposite buildをサポートした。
別々の複数のプロジェクトや同じプロジェクトの一部のビルドを一つのビルドに含めることができる。
これまでもサポートしていたが、部分的にしかサポートしていなかったらしい。
chigichan24.icon これまではどうだったのかがわからない。
試すにはgradle.propertiesの以下をon
kotlin.mpp.import.enableKgpDependencyResolution=true
composite buildだけでなく、importまわりのバグを修正して体験を良くしているらしい。
Known issues
rootProject.name を使うビルドが含まれている時、composite buildでKotlinのmetadataの解決に失敗することがある
Improved output for Gradle errors in Xcode
multiplatform projectでXCodeを使っていたときに、Command PhaseScriptExecution failed with a nonzero exit code というメッセージだけを残して死ぬことがあった。
これは開発者にとってどこで問題が起きているのかがわからない。
Mori Atsushi.icon よくある、つらい
Kotlin1.8.20-RC2から、XCodeはKotlin/Nativeコンパイラの出力をパースできるようになった。
chigichan24.icon えらい
https://scrapbox.io/files/642c197489d179001cb9c284.png
XCodeのcongigurationでembedAndSignAppleFrameworkForXcode を on にするか、gradle propertyでkotlin.native.useXcodeMessageStyle をonにすることで使えるようになる。
Standard library
AutoCloseableインターフェースのサポート
共通化して使えるように、AutoCloseableのインターフェースが追加された
code:kotlin
interface AutoCloseable {
fun close()
}
マルチプラットフォームに対応
JVMはjava.lang.AutoClosableのタイプエイリアス
lambda式を抜けた時にcloseするAutoClosable.use { }も提供
Base64のエンコード/デコードが追加
Base64.Default, Base64.UrlSafe, Base64.Mime
Kotlin/Native での @Volatile のサポート
@Volatileをつけると、マルチスレッドで見た時に常に最新の値が取得できるようにする
スレッド上のキャッシュを無効化する(ので遅くなる可能性がある)
書き込みを制御するわけではないので、mutexは別途対応が必要
chigichan24.icon おっ
今までJVMのみに対応していたが、JVMとKotlin/Nativeで共通で使える
多分new memory managerあたりかな
kotlin.jvm.Volatileではなくkotlin.concurrent.Volatileを使う必要がある
Kotlin/Native で正規表現を使用する場合のスタック オーバーフローのバグ修正
気になるポイント
メモ
コメント