LoginSignup
1
1

More than 5 years have passed since last update.

Kotlinのsafe call演算子とUnitの話

Last updated at Posted at 2015-09-01

Safe-call演算子

Kotlin書く人でSafe-call演算子?.を使わない人は少ないんじゃないかと思います。
それだけ当たり前に使う演算子なのですが、先日軽くはまったところがあるので、紹介します。

class A {
 fun foo():Unit = Unit
 fun bar():Int = 0
}

こんなクラスがあったとします。
それをこんな風に使います。

 val a : A? = null
 a?.foo()
 a?.bar()

まあ、思った通りに動きます。a==nullなので、foo()もbar()も実行されません。

では、これならどうでしょう?

 val a : A? = null
 a?.foo() ?:hoge()
 a?.bar() ?:huga()

hoge(),huga()が両方とも実行されて欲しい、というケースです。

これ、なぜかIDE上ではa?.foo()のところに警告が出ます。Elvis Operator (?:) always returns the left operand of non-nullable type Kotlin.Unit
どうやら、foo()はUnitを返すので、a?.foo()もUnitになりnullにはならない、よってエルビスの右辺は実行されないよ、と警告されているようです。
警告を信じている限り、hoge()は実行されないように思われます。
bar()の方はIntを返すので、a?.bar()がInt?と解釈されるので問題ない、ということのようです。

では、実行してみましょう。

=========: HOGE
=========: HUGA

あれ?

hoge()が実行されてますね。

どうも、コンパイラとエラーチェッカーの間に齟齬があるようです。

まとめ

nullable?.let { doit() } ?: instead()

こんな風に?.let { }を交えた構文を

if ( nullable != null ){
  doit()
}else{
  instead()
}

の代わりとして、手癖で覚えてたらIDEに警告されて悩んだ、という話でした。

個人的には、警告の解釈の方が筋が通ってるように思えるんですが、
動いてる方が正しいとも言えるわけで……難しい。

いまのところ、警告を無視するしか無さそうです。

1
1
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
1
1