【Kotlin】レッスン2-4:スマートキャストの基本と使い方|安全な型チェックを実現しよう

ながみえ

一つ前のページではwhen文による分岐処理について学習しました。

今回は スマートキャスト について見ていきましょう。

Lesson1:基礎文法編
Lesson2:制御構造編

 ・Lesson2-1:比較演算子と論理演算子を理解しよう
 ・Lesson2-2:if文による分岐処理を理解しよう
 ・Lesson2-3:when文による分岐処理を理解しよう
 ・Lesson2-4:スマートキャストを理解しよう ◁今回はココ
 ・Lesson2-5:for文による繰り返し処理を理解しよう
 ・Lesson2-6:while文による繰り返し処理を理解しよう
 ・Lesson2-7:繰り返しを制御しよう
 ・Lesson2-8:エラーメッセージを読めるようになろう
 ・Lesson2-9:例外処理を理解しよう
 ・確認問題2-☆1:ハイアンドローゲームを作ろう
 ・確認問題2-☆2:数字当てゲームを作ろう
 ・確認問題2-☆3:簡単なじゃんけんゲームを作ろう
Lesson3:関数編
Lesson4:コレクション編
Lesson5:オブジェクト指向編

<<前のページ

学習記事一覧

次のページ>>

スマートキャストとは何か|使い方とコード例

スマートキャストとは、型チェックのあとで自動的に変数の型を絞り込み、キャスト(型変換)なしで安全に扱えるようにしてくれる機能です。

この機能を使うことで、より安全で簡潔なコードを書くことができます。

まずはキャスト(型変換)とは何かという点から細かく見ていきましょう。

キャストとは?|明示的型変換とそのリスク

キャスト とは、ある型のデータを別の型に変換する操作のことです。

たとえば数値を文字列として扱いたい場合などにキャストを行います。

Kotlinでは asキーワード を使って明示的にキャストを行うことができます。

val obj: Any = "Kotlin"			// Any型の定数objの宣言
val str: String = obj as String	// objをString型にキャストし、定数strに代入
println(str)					// 文字列を出力

val num: Int = obj as Int		// ClassCastExceptionエラー

ただし明示的なキャストにはリスクがあります。

コードの5行目(”Kotlin”を数値にキャスト)のように、不可能なキャストを指示すると ClassCastExceptionエラー となります。

この問題を解決するのがスマートキャストです。

Any型:あらゆるオブジェクトを格納できる。
型が不明なデータを一時的に格納したい場合などに使われる。

スマートキャストの仕組みと基本的な使い方

スマートキャストは変数の型を is演算子 でチェックした後、その型に基づいて安全に変数を扱える便利な仕組みです。

例えばある定数がString型かどうかを確認した後、そのまま文字列操作を行えます。

if文の中で使用する例

if文の中でスマートキャストを使用する例を見てみましょう。

fun main() {
    val obj: Any = "Hello, Kotlin"	// Any型の定数objの宣言

    if (obj is String) { // もしobjの型がString型として使用できるなら
        // スマートキャストが適用され、objは自動的にString型として扱われる
        println("これは文字列です}")
    } else {
        println("文字列ではありません")
    }
}

上記の例ではis演算子を使って型チェックを行った後、objは自動的にString型として扱われています。

これがスマートキャストの基本動作です。

when文の中で使用する例

以下はwhen文を使って異なる型に応じた処理を実行する例です。

fun main() {
	val obj: Any = 42	// Any型の定数objの宣言

    when (obj) {		// objの型が...
        is String -> println("これは文字列です")  // String型として使用できるなら
        is Int -> println("これは整数です")	   // Int型として使用できるなら
        is Boolean -> println("これは真偽値です") // Boolean型として使用できるなら
        else -> println("これは未対応の型です")   // どの型として使用できないなら
    }
}

このコードを実行すると以下のように出力されます。

これは整数で、値は 42 です

nullチェックと組み合わせて使用する例

is演算子でのチェック結果は真偽値で返ってきます。

Any?型(nullable)を使用すれば、スマートキャストを使ってnullチェックも簡単に行えます。

fun main() {
    val obj: Any? = null		// nullも許容するAny型の定数objの宣言し、nullを代入

    if (obj is String) {		// 型チェック(True か Falseか)
        println("これは文字列です")
    } else if (obj == null) {	// もしobjがnullなら
        println("これはnullです")
    }
}

このようにしてnullチェックと型チェックを組み合わせて判定することが可能です。

var変数はスマートキャストが使えない?

スマートキャストは非常に便利は機能ですが、varで宣言された変数などには使用できないケースがあります。

fun main() {
    var obj: Any = "Hello"	// Any型の変数objの宣言
    if (obj is String) {	// もしobjの型がString型として使用できるなら
        // スマートキャストは動作しない場合がある
        // println(obj.length) // コンパイルエラーになる可能性
        println("これは文字列です")
    } else {
        println("文字列ではありません")
    }
}

スマートキャストの対象は、主に値が変わらないval定数やローカル変数です。

変数は値が変更される可能性があるため、型の安全性が保証できないためです。

まとめ|安全な型操作の第一歩

スマートキャストは、Kotlinを使ったプログラミングを簡潔で安全にする強力な機能です。

  • 型チェック後に自動的にキャストが適用される
  • コードの可読性が向上する

これを活用して、効率的でミスの少ないコードを書いてみましょう!

練習問題|スマートキャストで型を自動判定しよう

数値または文字列を入力すると、それに応じて適切な処理を行うプログラムを作成してください。

数値であればその2倍の値を表示し、文字列であればその文字数を表示します。

この問題を通じて、Kotlinのスマートキャストの使い方を学びましょう。

この問題の要件

以下の要件に従ってコードを完成させてください。

  1. ユーザーに「文字列または数値を入力してください」と表示し、入力を受け取ること。
  2. 入力された値をAny型の定数に格納すること。
  3. スマートキャストを使用し、入力された値が以下の場合に応じた処理を行うこと:
    • 数値として解釈できる場合は、数値として2倍した値を表示する。
    • 数値として解釈できない場合は、文字列としてその文字数を表示する。
  4. 数値への変換にはtoIntOrNull()を使用し、nullの場合は文字列として処理すること。

ただし、以下のような実行結果となること。

文字列または数値を入力してください:
42
入力は数値として認識されました。2倍にすると: 84
文字列または数値を入力してください:
Hello
入力は文字列です。長さは: 5 文字です。

この問題を解くヒント

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

Q
ヒント1【コードの構成を見る】


正解のコードは上から順に以下のような構成となっています。

1:main関数の定義
  □ 「文字列または数値を入力してください:」と出力
  □ readLine関数を使ってユーザーからの入力を取得し、変数inputに代入
  □ if文でinputがString型か判定
  □ □ 変数numberにinputをtoIntOrNullで整数変換(数値変換を試行)
  □ □ if文でnumberがnullでないか判定
  □ □ □ 真の場合、「入力は数値として認識されました。2倍にすると:」と数値を2倍にした結果を出力
  □ □ □ elseで「入力は文字列です。長さは:」と文字列の長さを出力

Q
ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

fun main() {
    // 入力された値が数値か文字列かを判定して適切に処理を行うプログラム

    println("文字列または数値を入力してください:")
    val input: Any = readLine() ?: "" // ユーザーからの入力を取得 (nullの場合は空文字に)

    // スマートキャストを使って型に応じた処理を実施
    /*【穴埋め問題1】
    ここでinputがString型であるかを判定するif文を書いてください。
    */
    {
        // 入力が文字列だった場合
        /*【穴埋め問題2】
        ここでinputを数値に変換するコードを書いてください。ただし変換に失敗する場合にnullを返すコードにしてください。
        */

        /*【穴埋め問題3】
        ここで変数numberがnullでない場合の処理を書くif文を書いてください。
        その中で、数値を2倍にした結果を表示するコードを書いてください。
        */

        /*【穴埋め問題4】
        ここで変数numberがnullの場合の処理を書くelse文を書いてください。
        その中で、文字列の長さを表示するコードを書いてください。
        */
    }
}

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。

この問題の解答と解説

この問題の正解コードとその解説は以下の通りです。

クリックして開いて確認してください。

Q
正解コード
fun main() {
    // 入力された値が数値か文字列かを判定して適切に処理を行うプログラム

    println("文字列または数値を入力してください:")
    val input: Any = readLine() ?: "" // ユーザーからの入力を取得 (nullの場合は空文字に)

    // スマートキャストを使って型に応じた処理を実施
    if (input is String) {
        // 入力が文字列だった場合
        val number = input.toIntOrNull() // 数値に変換できるか試す (Null安全性の利用)
        if (number != null) {
            println("入力は数値として認識されました。2倍にすると: ${number * 2}")
        } else {
            println("入力は文字列です。長さは: ${input.length} 文字です。")
        }
    }
}
Q
正解コードの解説

コードをブロックごとに分割して解説します。

入力を受け取る処理

println("文字列または数値を入力してください:")
val input: Any = readLine() ?: ""
  • printlnは画面に文字列を表示します。「文字列または数値を入力してください」というメッセージを出します。
  • readLine()はユーザーからの入力を文字列として受け取ります。
  • ?:は「エルビス演算子」と呼ばれ、readLine()nullを返す場合、代わりに空文字""を代入します。
  • inputAny型の変数として宣言されます。これはあらゆる型の値を格納できるKotlinの最上位型です。

スマートキャストの基本

if (input is String) {
    val number = input.toIntOrNull()
    if (number != null) {
        println("入力は数値として認識されました。2倍にすると: ${number * 2}")
    } else {
        println("入力は文字列です。長さは: ${input.length} 文字です。")
    }
}
  1. スマートキャストのポイント:
    • if (input is String)の部分で変数inputString型であることをチェックしています。
    • この型チェックが真の場合、inputは自動的にString型として扱われます(これがスマートキャストです)。そのため、追加のキャスト操作は不要です。
  2. 数値の判定と処理:
    • toIntOrNull()は文字列を数値(Int型)に変換します。変換できない場合はnullを返します。
    • 変換が成功した場合(number != null)、数値として2倍した結果を表示します。
    • 変換が失敗した場合は、文字列としての情報(長さなど)を表示します。
  3. コードの特徴:
    • スマートキャストによりコードの安全性と簡潔さが向上しています。
    • nullチェック(toIntOrNullの結果確認)も組み合わせることで、エラーの発生を防いでいます。
Q
サイト改善アンケート & ご指摘/ご質問

本サイトでは、みなさまの学習をよりサポートできるサービスを目指しております。
そのため、みなさまの「プログラミングを学習する理由」などを アンケート 形式でお伺いしています。

また記事の内容に関する ご指摘ご質問 もお待ちしています。

1.このサイトをどのように活用していますか?また、今後どのように活用したいですか?
5.気になっているサービス・商品があれば教えてください。
※ 特定の記事に関する内容の場合は、記事番号(レッスン〇-〇)をご記入願います。

<<前のページ

学習記事一覧

次のページ>>

記事URLをコピーしました