2015-09-10

Kotlinことはじめ:(8)Nullセーフティ

KotlinはNullPointerException(以下ぬるぽ)を言語レベルで防ぐ仕組みを持っています。

Null許容型と非Null型


Kotlinの型は基本的にNullを保持することができません。
Nullを保持する変数を宣言するには、型名の後ろに「?」を着けます。

var notNull: Int = null // エラー

var nullable: Int? = null // OK

Nullの可能性があるとアクセス出来ない

Null許容型の変数に入っているオブジェクトにアクセスしようとする場合、Nullの可能性があるとエラーになります。

var nullable: String? = "abcde"

println(nullable.length()) // エラー

条件によるNullチェック

Nullチェックを行うことで、Null許容型にアクセスすることができます。

var nullable: String? = "abcde"

if (nullable != null) {

    println(nullable.length()) // OK

}

セーフコール演算子

「?.」がセーフコール演算子です。

var nullable: String? = "abcde"

println(nullable?.length()) // OK
「.」の代わりに「?.」を使用すると、ぬるぽを投げる代わりに、nullを返すようになります。

エルビス演算子

前の式がnullを返す場合に代わりの値を指定するのに使えるのが、エルビス演算子です。

var nullable: String? = null

println(nullable?.length() ?: -1)
この場合、変数nullableがnullだと、-1を返します。

!!演算子

この演算子は、ここまでのぬるぽが投げられるのを避けるための仕組みを回避して、ぬるぽを投げるようにします。

var nullable: String? = null

println(nullable!!.length())
この場合、コンパイルエラーにはなりませんが、ぬるぽが発生します。

セーフキャスト

これはぬるぽとは関係ないですが、プログラムミスによる例外を無くすという意味では近い。
型キャスト時に互換のない型を指定すると、ClassCast Exceptionが発生しますが、Kotlinにはこれを防ぐ構文を持っています。
通常キャストは、

val value = "String"

val casted = value as Int // エラー

println(casted)
のように「as」で行いますが、

val value = "String"

val casted:Int? = value as? Int //OK

println(casted)
のように「as?」とすることで、例外を発生させる代わりに、nullを返します。

3 件のコメント:

ngsw_taro さんのコメント...

勉強させていただいております。
質問ですが、行方不明演算子ってなんですか?
?: はエルビス演算子と呼ばれることが多い印象があり、公式サイトでも「Elvis Operator」との表記があります。

Unknown さんのコメント...

ありがとうございます。
こちらこそ、いろいろと参考にさせていただいてます。
「Elvis」という単語が行方不明者を表すスラング(亡くなっているはずなのに定期的に目撃者が現れるエルヴィス・プレスリーに由来?)なので、演算子の役割との兼ね合いから、この訳語をつけました。
#調べてみたら、エルヴィス・プレスリーは合ってるけど、文字の形からきてるんですね (^_^;)
他の言語でも一般にエルビス演算子で通っているようなので、エルビス演算子に直します。

ngsw_taro さんのコメント...

ご回答ありがとうございます!
そんなスラングがあったんですねw