LoginSignup
57
64

More than 5 years have passed since last update.

Kotlin 0.12からKotlin 1.0.2にアップグレードした際にやったこと

Last updated at Posted at 2016-06-06

Kotlin 0.12からKotlin 1.0.2にアップグレードした際にやったこと

Kotlinが1.0系になり、言語仕様が安定してきたとの事(後述)なので、
技術的な検証として、過去にKotlin 0.12で作ったアプリのKotlin 1.0.2へのアップグレード対応を試してみました。

コンパイラバージョンを切り替えたところ、1800個のコンパイルエラーが生じましたw
同じような境遇の方は少ないと思いますが、自分の事例を紹介します。

作業時間

上記の修正ですが、合計で3時間ほどの作業でコンパイルできるようになりました。
特に困難なものもありませんでした。

言語仕様の安定性について

公式のKotlin 1.0についての記事によると、

As of 1.0, we are committed to long-term backward compatibility of the language and its standard library (kotlin-stdlib):

と書いてあります。
0系から1系での追従でも大したことはなかったので、
今後のアップグレード追従についてはだいぶ楽観視できます。

import asでパッケージに別名を付けることができなくなった

jp.co.aaa.hogeネームスペースにHogeクラスが定義されている場合、
以前は下記のように書くことができました。

import jp.co.aaa.hoge as hoge

val x = hoge.Hoge()

しかし、このようにパッケージレベルで別名を付けることができなくなってしまいました。
上記のケースでは、Hoge自体に別名をつける必要があります。

import jp.co.aaa.hoge.Hoge as HogeHoge

val x = HogeHoge()

前者の方法であれば、jp.co.aaa.hogeの中にどのようなクラス名が入っていても、
別名のhogeさえ衝突しないのであれば、hoge.XXX表記を使う限り衝突の心配が無かったのですが、
できなくなってしまい残念です。

Javaのクラスのメソッド名がKotlin風に変更された

java.util.Listで要素数を取得するsize()メソッドは、
以前はlist.size()のように呼ぶことができました。

今のKotlinではこれはsizeプロパティに変更されています。
呼び出し部分の丸括弧があるとコンパイルエラーになります。

このようにJavaのクラスのメソッド名が、
Kotlin風のメソッド名やプロパティに変更されました。
多くの変更がされているようですが、
僕が踏んだものを掲載します。

array.length()->array.length
list.size()->list.size
list.reverse()->list.reversed()
list.remove()->list.removeAt()
map.values()->map.values
map.keySet()->map.keys
map.entrySet()->map.entries
entry.getKey()->entry.key
entry.getValue()->entry.value

あちこちで踏んでいたので修正には手間がかかりましたが、
修正後の仕様は綺麗なものばかりで、個人的には嬉しい修正です。

Mapの要素アクセスがnullableを返すようになった

上記のjavaライブラリの変更とも関係して、
Map<T>の要素アクセスmap[key]で以前はT!を返していたものが、
T?を返すようになりました。
T!で来ている部分をTで扱っていたケースでコンパイルエラーになります。

既存コードは既にテストされているものだったので、
マイグレーションとしては!!を付けるだけの修正でした。

プロパティのバッキングフィールド名が変更された

以前はプロパティ名propに対して、$propというドル記号プレフィックスをつけたものが、
バッキングフィールドとして暗黙定義されていましたが、
fieldという固定のキーワードに変更されました。

オペレータオーバーロードにoperatorキーワードが必要になった

以前はfun plus()のようなメソッドを定義すれば、
それだけで+演算子の実装を与えることができました。
それが、operator fun plus()のように、
operatorキーワードの指定が必要になりました。

単項演算子の関数名が変更された

以前は単項演算子の+-plusminusでした。
これがunaryPlusunaryMinusに変わりました。
二項演算子はplusのままです。

アノテーションに@がついて、命名が変わった

suppress("UNUSED_PARAMETER")などと書いていたところが、
@Suppress("UNUSED_PARAMETER")と書くように変わりました。
@がついてアッパーキャメルケースになり、Javaの仕様に近づきました。

変数名_が予約された

クロージャ引数を読み捨てるようなケースで、
それをあらわすルールとして_という変数名を使ったりしていましたが、
これがコンパイルエラーになりました。

Swiftで明示的に読み捨てる場合、let _ = ...と、
_を使うのでそれに似せて使っていたのですができなくなってしまいました。

ジェネリック関数の型パラメータ指定位置が変わった

ジェネリック関数の型パラメータの指定位置が変わりました。
以前は下記のように関数名とパーレンの間に書きました。

fun hoge<T>(arg: T)

現在は下記のようにfunと関数名の間に書きます。

fun <T> hoge(arg: T)

前者の仕様だとswiftと同じ位置なのでわかりやすかったのですが、
変わってしまいました。

Javaクラスオブジェクトの取り出し方が変わった

以前のjava.lang.class<T>の取り出しはjavaClass<T>()でした。
これがT::class.javaに変わりました。

AndroidのIntent呼び出し箇所で使うため、
かなり多くの修正箇所がありました。

新しい仕様のほうが、
T::classがKotlinでのクラスオブジェクトで、
それのjavaプロパティとしてJavaでのクラスオブジェクトが取り出せる形なので、
とてもわかりやすくなっていて良いと思います。

Deprecation警告の抑制アノテーションが変わった

以前はsuppress("DEPRECATED_SYMBOL_WITH_MESSAGE")だったのですが、
@Suppress("DEPRECATION")と変わりました。

わかりやすい名前になって良かったです。

57
64
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
57
64