Swiftとkotlinの⁉(optional型、nullable)の考察
Swift と kotlin の⁉
(Swift4 Kotlin1.2)
結論
OptionalやNullableは、nilを変数の状態フラグとして用いる必要がある場合にのみ用いる。
そうではないpropertyやauto変数については、二度手間になったとしても初期値を設定する、もしくはgetter methodを定義したり、lazy lambdaを定義することによって変数を初期化する。
-
「無」という概念はインド人がアラビア数字とともに発明したものだ。
無という概念は「何もないが、全てがある状態」である。
物理的には存在すらしない状態を表している。
誤解を恐れずに言えば、無は「start スタート」と同意である。
あるいは、「まだ何もしていない無垢なる状態」とも表現することができるのである。
プログラミングというのは社会科学の結果を計算式に翻訳する作業であるので、「無垢な状態」かどうかをコンピュータに認識させる必要が出てくる。
レガシーなプログラミングではアラビア数字の0(ゼロ)を、ある変数に値がセットされているかどうかの指標にしていた。
値として0を扱う場合があるため、0ではなくnullというニーモニックを使うことにした。
しかし、コンピュータにはnil やnull と0は同じ値に見える。
値がセットされていない0なのか、0という値がセットされているのかは人が見分けなければならなかった。
そこで、世界一の企業の精鋭が考えた最新の言語であるswift そしてKotlin ではNilは扱わないことにした。
だが、プログラムでは、値を持たない状態が必要になる。
値を保持する変数とnilフラグ変数をそれぞれ持てば解決するものの、非常にわかりづらいし、煩雑だしかえってバグを誘発する。
そのため、変数自体に値を持っているかどうかのフラグを持たせた。
Optional 型(nullable)の誕生である。
Nilは変数に値がセットされているかどうかのフラグとしてのみ使うことにしたのだ。
物事には良い面があれば必ず悪い面がある。
ObjcやJavaは、「おまじない」が多くお世辞にも直感的なプログラムが書けるとは言えなかった。
その反面、objc では、あるクラスインスタンス変数の値がnilなら実行をスルーする(実行しないで次に進む)という「良い」特徴があった。
swiftでは、framework実装自体にoptionalが多用されていて、frameworkクラスのインスタンスのpropertyやmethodを使うには必ず?を付ける必要がある。
Swiftは、nib outlet した変数を必ず使うが、その全てに!をつける必要がある。
また、property変数宣言時にnil以外で初期化できない変数には全て?をつける必要もある。
その変数がクラスのインスタンスならgetter で値を参照したり、メソッドをinvoke するときには必ず?を付けなければならない。
そしてswiftプログラムは!?だらけになる。
翻って、kotlinではインスタンス変数に対し lateinit やby lazyブロックが使えるため、⁉だらけのプログラムにはならず、直感的にプログラムできる。
Optional やNullableは、nilを変数の状態フラグとして使用する必要がある場合にのみ用いることを強く勧める。
-
optional型またはnullable
(Nilかどうかのbool値を持つ変数)
アンラップとは型変換(Int? → Int)のこと。
StringとString?とは全く異なる変数型である。
・変数宣言時(変数宣言時に値をセットしない変数)
swift
Swift:!
var initOnLaterVar : View!
(Nilで初期化される)
\*変数使用時に自動型変換(String! → String)され、値がNilなら異常終了する
kotlin:
lateinit var initOnLaterVar : View
Or
val viewInstance :View by lazy {
findViewById () as View
}
\*nib outlet など絶対に値がセットされる変数に使う
・変数宣言時(変数宣言時に値をセットしない変数)
swift
Swift:?
Kotlin; ?
var nullAbleVar : Int?
(Nilで初期化される)
・変数宣言時(変数宣言時に値をセットする変数)
swift
Swift:(なし)
Kotlin:(なし)
var nonNullVar : String = “ ”
Nilはセットできない
・実行時(型変換する(String? → String))
swift
Swift:!
var nonNullVar: String = nullAbleVar!
kotlin: ‼
var nonNullVar: String = nullAbleVar!!
\*値がNilでも型変換を試みる。
(Nilなら異常終了する)
・実行時(型変換(String? → String)してgetter やmethod をinvoke する)
swift
Swift:?
Kotlin:?
var abc: String? = nullAbleVar?.init()
値がNilなら実行せずNilを返す。
Nilでなければ実行する。
・実行時(nil判定と型変換(String! → String)を異常終了をともなわずに行う)
swift
Swift:
let nonnullableVar = nullableVar?.property ?? ""
Or
let nonnullableVar = nullableVar != nil ? nullableVar! : ""
Or
if let _ = optionVar {
// non null
// optionVarはnilでない
} else {
// null
}
Kotlin:
val nonnullabelVar = nullableVar ?: “”
Or
val nonnullabelVar = nullableVar ?: run {
ErrorLog()
}
Or
nonnullabelVar?.let {
// non null
// nonnullabelVarはnilではない
} ?: run {
// null
}
2023年12月 | ||||||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
  |   |   |   |   | 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |   |   |   |   |   |   |
iOS
web
?スA?スv?ス?ス?スフ抵ソス?ス??
?スu?ス?ス?スb?スN?ス`?スF?ス[?ス?ス?ス^?ステ搾ソス?スZ?スp
?スV?ス?ス?ス?ス?スミ会ソス
?スT?スE?ス?ス謨ァ?ス?ス
?ス?ス?ス{?スフなりた?ス?ス