各言語の違い(無との付き合い方)

公開日:2019-05-20
最終更新:2019-06-18

無とはいったい・・・

改めて説明しようと思うと難しいよね…
Java、Kotlinでは"null"、Swiftでは"nil"で表現するアレ。
型は決まっているけど存在していない。数字の0とはまた違う。

値として存在しないのに存在している。よくわからんやつだ。
オブジェクトがメモリ上に存在していないという感じ?

こいつとの付き合い方はよく考えなくてはいけない。
なぜなら無の状態のオブジェクトのメンバーにアクセスしようとしても何も無いので何も出来なくて困ってしまい基本アプリは死ぬ。つまり死ぬのでとても危険。

虚無…
https://nlab.itmedia.co.jp/nl/articles/1702/22/news143.html

無を許容しない

危険なので、無を許容しないようにしていきたいという考えがある。

Kotlin、Swiftはも何もせずに変数を宣言した場合、その変数は"無"を許容しない。
Javaは"無"を許容する。

例えば、Integer型の変数 value を null で初期化してみるとどうなるか。

//Java  
Integer value = null;  

これは可能。

KotlinやSwiftだとどうなるか。

//Kotlin  
val value: Int = null  
//Swift  
let value: Int = nil  

両方ともコンパイル時にエラーになる。

他にも、初期化済みのInteger型の変数 value に null を代入してみる。

//Java  
Integer value = 42;  
value = null;  

もちろん、これは可能。

KotlinやSwiftだとどうなるか。

//Kotlin  
var value = 42  
value = null  
//Swift  
var value = 42  
value = nil  

両方ともコンパイル時にエラーになる。
無を許容しないことで、虚無へのアクセスから逃げることが出来る。

無を許容する

と言っても、無を許容しないといろいろ面倒なので無を許容しつつもNPEを極力排除するためにNull安全で立ち向かう。

無を許容する宣言

//Kotlin  
var value: Int? = null  
//Swift  
var value: Int? = nil  
var value: Int! = nil  

このように、Koltinは型名の直後に "?" を、Swiftは型名の直後に "!" または "?" を付けることで無を許容する事が可能になる。
Swiftはこの宣言をOptional型と呼ぶ(?と!では少し意味合いが違うが)

無を許容した変数にアクセスしてみる

では、無を許容した変数は自由に使えるのだろうか。

無を許容した変数に変更を加えてみる

//Kotlin  
var value: Int? = 42  
value += 1  
//Swift  
var value: Int? = 42  
value += 1  

両方ともコンパイル時にエラーになる。
このコードでは確実に無でないことはわかるが、コンパイラは確実に止めてくる。

Kotlinでは変数が無でないことが保証されていないためだったり、
SwiftではOptional型に非Optional型の値を入れる事が出来ない為。
さらには、Optional型にOptional型の値を入れる事も出来ない。
SwiftのOptional型は中の値に触ろうとすると怒られてしまうのだ。

Optional型と非Optilnal型は違うんだぞ

Optional Intの42と、Intの42でも42は42じゃないかと思うけれども型が違うのでしょうがないのよ。

次のようなコードを実行するとわかるかもしれない。

//Swift  
var value: Int = 42  
var opValue: Int? = 42  
print("非Optional = \(value)")  
print("Optional = \(opValue)")  

これは次のように表示される
非Optional = 42
Optional = Optiona(42)

ね、違うでしょ。

無許容型の値を使うには

じゃあどうするのか。

Koltinの場合

スマートキャスト

直前にnullチェックを行ってやる。

//Kotlin  
var value: Int? = 42  
if (value != null) {  
    value += 1  
}  

ifブロックの中はvalueがnullではない事が確定しているのでセーフ。

安全呼び出し

変数名の直後に"?"を付けてやることで、nullの場合は何もせず、そうで無い場合はオブジェクトのメンバを呼び出す事が出来る。

//Kotlin  
var value:  String? = "Not Null"  
print(value?.length)  

拡張関数letを使う

安全呼び出し後に.letを呼び出すと、直後のブロックに暗黙変数itとしてnullでは無い自身が渡される。

//Kotlin  
var value:  String? = "Not Null"  
value?.let { print(value.length) }  

ブロック内のvalueはnullでない事が確定しているのでセーフ。
よくみると、 value!.lengthでなくvalue.lengthになってるのもポイント。

!!演算子を使う

null許容状態の変数を強制的に非null許容状態と変換できる。

//Kotlin  
var value:  String? = "Not Null"  
print(value!!.length)  

ただし…

//Kotlin  
var value:  String? = null  
print(value!!.length)  

これをやると例外が発生するので、このアクセスは極力行わないようにしたい。

Swiftの場合

Optional型というのは、基本の型(IntとかStringとか)を包み込んでいる包み紙(ラップ)という感じ。
それ故に、Optional型から値を取り出すことを「ラップしているものから取り出すこと」つまり「アンラップ」と言う。

強制アンラップ

オプショナル型の変数名の後ろに "!" を付けることで変数内の値を取り出す事ができる。

//Swift  
var value: Int? = 42  
print(value!)  

Optional型をそのまま表示すると Optiona(42) となるが、
"!"を付けることで 42 と表示される。

しかし、nilが入っているOptional型を強制アンラップするとエラーとなってしまうので注意。

オプショナルバインディング

オプショナル型の変数を別の変数に代入し、if-let文で判定する。
if let 変数 = オプショナル型の変数 { nilじゃない場合の処理 } else { nilの場合の処理 }

//Swift  
var value: Int? = 72  
if let unwappedValue = value {  
    print(unwappedValue)  
} else {  
    print("残念、nilでした!")  
}  

オプショナルチェインニング

オプショナル型の変数の後ろに "?" を付け、プロパティやメソッドを呼び出す。

//Swift  
var value:  String? = "Not Null"  
print(value?.length)  

変数がnilだった場合にプロパティやメソッドにアクセスをした場合、 nil が返される。

暗黙的アンラップ型

変数の宣言時に、型名の後ろに "!" を付ける。
強制アンラップじゃないよ.

var value: String!

この宣言を行う事で、この変数は使用時に強制アンラップされる。

例えば、通常のオプショナル型では次の処理ではエラーになる。

//Swift  
var value: Int = 42  
var opValue: Int? = 42  
print(value + opValue) // エラー  

アンラップせずに処理を行おうとしたからだ。

暗黙的アンラップ型で宣言すると

//Swift  
var value: Int = 42  
var opValue: Int! = 42  
print(value + opValue) // 84が表示される  

これはエラーにならない。暗黙的アンラップ型なので使用時に自動でアンラップされるからだ。
しかし、暗黙的アンラップ型の中がnilだった場合、エラーになるので使い所には要注意。

記事が少しでもいいなと思ったらクラップを送ってみよう!
1
+1
偉大な先人が切り開いた道だろう。しかし、それでも自分は初めて通る道なのだ。そして、これは自分の為に記していくのだ。

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする