あまり推奨されない方法
Kotlinでデータの型をチェックする方法として、まずは『絶対ダメというわけではないけれど、あまりオススメはしないよ』 …という方法からご紹介します。
Kotlinで変数のデータ型を調べる際、class.simpleName
がよく使われます。例えば、整数(Int)を格納している変数に対して使用すると、“Int”という文字列を得ることができます。
var number = 10
fun main () {
println (number ::class .simpleName ) // Outputs: Int
}
▼
なので、これを利用すれば変数の型チェックを行うことも不可能ではありません。下に示すコードは、class.simpleName
を利用して型チェックを行っている例です。
var number = 10
fun main () {
if (number ::class .simpleName == "Int ") {
println ("number is Int ")
} else {
println ("unknown ")
}
// Outputs: number is Int
}
▼
Kotlinは静的型付け言語であり、このコードにおける条件分岐は常に true
となるため、そもそもこの例では条件分岐が不要なのですが、そこはあまり気にしないでください。
上のサンプルコードは一見、何の問題もないように思えますが、変数の型を Any?
で指定するとコードが少し複雑になり、また変数が null
である場合のエラーハンドリングなどが必要になってきます。
下のコードは、変数anyTypeData
の型を Any?
で指定し、整数(Int)を代入した上で、これまでと同様に class.simpleName
で型チェックを行った例です。
var anyTypeData : Any? = 10
fun main () {
if (anyTypeData != null && anyTypeData !!::class .simpleName == "Int ") {
println ("data type is Int ")
} else {
println ("data type is other ")
}
// Outputs: data type is Int
}
▼
なんだかコードがごちゃごちゃしてきましたね。
一応、『データ型をチェックする』という目的は果たせていますが、読みやすいコードであるとは言えません。
では、どのようにチェックを行うと良いのでしょうか?次のステップで確認していきましょう!
POINT!
・class.simpleNameでデータの型を文字列として得ることはできるが…!?
・nullである場合の対処が必要など、コードが冗長かつ複雑になってしまう場合がある!
型チェックのベストプラクティス
Kotlinにおいて、データの型をチェックする際は、is
演算子を用いると、直感的に分かりやすくシンプルなコードを書くことができます。
先ほど class.simpleName
を使って条件分岐を記述したコードを is
を使って書き直すと、次のようになります。
var anyTypeData : Any? = 10
fun main () {
if (anyTypeData is Int ) {
println ("data type is Int ")
} else {
println ("data type is other ")
}
// Outputs: data type is Int
}
▼
だいぶスッキリしましたね!ご覧の通り、is
は null
に対しても安全に使用することができるので、値が null
かどうかで処理を分ける必要がありません。
anyTypeData
の値が null
だった場合は単純に false
を返すだけなので、elseブロックの処理が実行され、“data type is other”が表示されることになります。
もちろん、is
演算子は when
を使ったケース別の処理にも使用できます。
var anyTypeData : Any? = 10
fun main () {
val dataTypeInfo = when (anyTypeData ) {
is Int -> "Int "
is String -> "String "
is Boolean -> "Boolean "
else -> "Other type "
}
println (dataTypeInfo ) // Outputs: Int
}
▼
このように、複数のデータ型別に処理を分けたいケースでも、is
演算子を利用することでコードの可読性が高まり、その意味や意図の理解が容易になります。
また、ここまではプリミティブ型で例を示してきましたが、ユーザー定義の型(独自に定義したclassなど)をチェックする際も is
は有効です。
下は、data class
として定義された User
と、変数に格納されたデータの型が一致するかどうかを判定している例です。
data class User (
val name : String ,
val age : Int
)
fun main () {
var anyTypeData : Any? = User ("Tom ",25 )
if (anyTypeData is User ) {
println ("""
anyTypeData is User
Name: ${ anyTypeData .name }
Age: ${ anyTypeData .age }
""".trimIndent() )
} else {
println ("anyTypeData is not User ")
}
/**
* Outputs:
* anyTypeData is User
* Name: Tom
* Age: 25
*/
}
▼
基本的なデータ型のチェックであれば、以上のポイントを押さえておくだけでも十分だと思います。
ただ、is
演算子はあくまで『データの型が比較対象と一致するかどうかを調べるためのものである』 という点には少し注意が必要です。
データ型のチェックを行うのではなく、型の名称を知りたい(デバッグのために文字列として表示させたいなど)という場合は、class.simpleName
の方が適しています。
目的に応じて、使用できる演算子やプロパティ、メソッド等を比較検討し、より適切なものを選択するのがベストと言えます。
POINT!
・is演算子を使うことで、シンプルに型チェックを行うことができる!
・is演算子はnullに対しても安全に使用できる!
・ただし、データの型の名称を知りたい場合などは class.simpleName などの方が適切!