Kotlin 1.2 の新機能


1.2 になって、どのような機能が追加されたのかをまとめてみました。

Annotation における Arrey 記述 の簡略化

従来はアノテーションの記述において、 Array 型 の引数を記述するときに arrayOf 関数 を使う必要がありましたが、 [ ] で囲むことでより簡単に記述することができるようになりました。

従来の書き方

1.2で可能になった書き方

トップレベル変数への lateinit 修飾子

従来はトップレベルの変数には lateinit を付けることができませんでしたが、それが可能になりました。

エラーの出る書き方

1.2 で可能になった描き方

従来はこのような書き方をするとエラーになりました。

例えば次のような場合に役に立つと思われます。

lateinit 修飾子 は、定数に使うことはできません。

そしてこの lateinit で修飾されたプロパティが初期化されているか否かを判定できるようになりました。 :: で プロパティ情報にアクセスし、 isInitialized で初期化情報を取得します。

プロパティ参照の簡略化

従来は、 クラス内で this::a のように書くとプロパティ参照ができていました。 これが 1.2 になってから、 ::a と書くだけでプロパティ参照できるようになりました。 これにより、ラムダ関数内でのプロパティアクセスが楽になりました。 (参考: https://youtrack.jetbrains.com/issue/KT-1566)

BigInteger, BigDecimal の演算子、変換メソッド追加

BigInteger, BigDecimal は、任意精度の数を扱えるクラスです。 Int, Long 等のクラスから BigInteger, BigDecimal に変換するための toBitInteger, toBigDecimal という関数が追加されました。 クラスと使えるメソッドの対応は下の表のようになっています。

toBigInteger toBigDecimal
Int O O
Long O O
Float O
Double O
BigInteger O

そして、これまで BigInteger, BigDecimal の計算では、 add, subtract, multiply, divide, remainder メソッドを記述する必要がありましたが、 2項演算子 +, -, *, /, %、 ビット演算子 and, or, xor, shl, shr、単項演算子 -, ++, -- が導入されて、ずっと記述が楽になりました。

小数表現とビットの相互変換

Double, Float について、 ビット表現に変換するメソッド toBits, toRawBits が実装されました。 返り値の型は次の表のようになります。

toBits, toRowBits
Double Long
Float Int

DoubletoBits, toRawBits は、それぞれ java.lang.Double.doubleToLongBits, java.lang.Double.doubleToLongRawBits を呼び出しています。 FloattoBits, toRawBits は、それぞれ java.lang.Float.floatToIntBits, java.lang.Float.floatToIntRawBits を呼び出しています。

実行例

ビット表現から Double, Float を生成する fromBits というメソッドも追加されました。 Double.fromBitsjava.lang.Double.longBitsToDouble を、 Float.toBitsjava.lang.Float.intBitsToFloat を呼び出しています。

toBits と toRawBits は、 NaN をどのように扱うかという点で違いがあります。 NaN は 指数部のビットが全て 1 で,仮数部のビットのどこかが 1 になっているものと定められています。 そのため toRawBits では、 ビット表現が異なれば、出力も異なる値になります。 一方、 toBits ではすべての NaN は同一の値 (Double.NaN) になります。

kotlin.text.Regex の Serializable 実装

クラス kotlin.text.Regexkotlin.io.Serializable を実装しました。 これにより、Regexオブジェクトが Serializable のオブジェクトとして扱えるようになり、一時的にオブジェクトを保存する際に Regex のオブジェクトもまとめてシリアライズできるようになりました。 kotlin.io.Serializablejava.io.Serializable の型エイリアスとなっています。

非推奨化: vararg 引数への単一値代入

vararg で記述されていた関数の引数について、これまではひとつの値でも次のようにして渡すことができていました。

これは直感的でないため、 1.2 からは非推奨となりました。 1.2 では test(v = *arrayOf(“test”)) というように、展開演算子を用いて記述する方法が推奨されています。

Kotlin の 1.2ベータ版公開時のブログには、 最終的には test(v = arrayOf("test")) のように書けるようにしたいと書かれており、 1.2 では段階的移項のためにこのようにしたとも書かれています。

従来の test(v = "test") のような書き方は、 1.2 では warning が表示されます。 1.3 では廃止される予定です。

非推奨化: Enum class のエントリの中でのクラス定義

Enum のエントリの中でクラスを定義することが非推奨となりました。 1.3ではエラーとなる予定です。

型推論の向上

型パラメータによって指定されたクラスの値を返します。

特に Android 開発では Android API level 26 から findViewById などでジェネリクスが導入されているので、この改善による恩恵は大きいです。

Kotlin 標準ライブラリ

Kotlin の標準ライブラリは複数のjarファイルで同一のパッケージのクラスを宣言できないという Java 9 のモジュールシステムと完全互換となりました。これにあわせて kotlin-stdlib-jre7, kotlin-stdlib-jre8 は非推奨となり、それに代わるライブラリ kotlin-stdlib-jdk7, kotlin-stdlib-jdk8 が導入されました。

拡張: windowd, chunked, zipWithNext

Iterable<T>, Sequence<T>, CharSequence に対して、バッチ処理に使うための chunked 関数、 スライドするための windowed 関数、 要素とその次の要素から作られる新しい要素列を作り出す zipWithNext が追加されました。

Listの拡張

MutableListfill, replaceAll, shuffle が、 Listshuffled が追加されました。

関数名 挙動
fill リストのすべての要素を書き換える
replaceAll リストの要素で該当するものを置き換える
shuffle リストの中身をランダムに入れ替える
shuffled リストの中身をランダムに入れ替えた新しいリストを作る

数値計算のためのライブラリ強化

数値計算のために、 kotlin.math API が追加されました。 π, e(自然対数) や三角関数、対数等が扱えるようになりました。

警告をエラーとして扱う

警告をエラーとして扱えるようになりました。 コマンドラインで オプション -Werror をつける方法と、 gradle に次のように書く方法があります。

super から呼び出す Java メソッド のエラー化

Java のメソッドを override して作成した Kotlin のメソッド内で、同一の関数を super を使って呼び出すとエラーになります。 ターゲットとなる JVM を 1.8 にすることでエラーが解消されます。