1.3のm1きましたわーい
Kotlin1.3 m-1での変更、追加点
-
coroutines
がexperimentalからstableになった -
when
の()
の中で変数宣言できるようになった -
@JvmStatic
と@JvmField
をcompanion object
内で使えるようになった -
annotation calss
をネストして宣言できるようになった。 - 新たに
inline class
が追加 - 符号なし整数型の追加
-
SuccessOrFailure
クラスの追加 - Multiplatform random number generator
-
Boolean
型にcompanion object
を追加 -
Collection
,Map
,Array
型の拡張関数isNullOrEmpty
の追加とSequens
型の拡張関数orEmpty
の追加
詳細
詳細については、inline class
についてをピックアップしたいと思います。
1.3-m1を使うには
kotlin-eap
のリポジトリを見に行く必要があります。
とりあえず、gradleのスクリプトをぺたり
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.3-M1"
}
repositories {
maven { setUrl("http://dl.bintray.com/kotlin/kotlin-eap") }
mavenCentral()
}
dependencies {
compile(kotlin("stdlib-jdk8"))
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
こんなかんじ、GradleのスクリプトをKotlinで書いてるけどgroovyの方でもまぁ大体一緒
inline classについて
inline class
には通常のクラスとは違って以下の制約があります。
-
primary constructor
に必ず一つのread-only
なproperty
のみを持つ必要がある -
backing field
を持つproperty
は定義できない
-
initializer block
を持てない -
===
での比較は不可能
等など、インライン展開されるので当然といえば当然の制約です。
なんか色々あるから漏れがあるかもしれない😔
簡単な例と、あとはコンパイルされた時のイメージをコードで表したいと思います。
inline class Age(private val value: Int) {
fun birthYear(): LocalDateTime {
//todo 雑
val now = LocalDateTime.now()
return LocalDateTime.of(now.year - value, now.month,
now.dayOfMonth, now.hour, now.minute)
}
}
fun main(args: Array<String>) {
val age = Age(14)
println(age.birthYear())
}
実行結果はこんなかんじ
2004-07-30T13:38
なんかprimary constructor
のプロパティはprivate
にもできるみたい
なぜ
main.kt
をコンパイルした際の動作の簡単なイメージとしてはこんな感じになります。
fun main(args: Array<String>) {
val age = 14
val var1 = Age$Erased.birthYear(age)
println(var1)
}
inline class
が持っているプロパティをその場に展開をして、メソッド呼び出しは関数呼び出しに置き換える感じ?(語彙力が無い)
なんでプロパティにprivate
を当てられるようになっているのかはよくわかんない。
typealias
に似てますけど、代入互換性はありません。
typealias
やプロパティへの命名と違ってある程度の制約を設けることが可能なので、使用用途としては既存の型のロールとそれに対する操作をまとめたりするのに便利そうだなぁという感想
追記
SuccessOrFailure
クラスがinline class
だったなぁと
こういう使い方ならたしかにinline class
のプロパティにprivate
が当てられるようにされてるのも納得しました