【Kotlin】レッスン1-4:Null安全性を理解しよう|安全なコードを書くための基礎知識

ながみえ

一つ前のページでは算術演算子について学習しました。

今回は Null安全性 について見ていきましょう。

Lesson1:基礎文法編
 ・Lesson1-1:Kotlin学習の入り口|初めてコードを書いてみよう
 ・Lesson1-2:変数と定数を理解しよう
 ・Lesson1-3:四則演算をしよう
 ・Lesson1-4:Null安全性を理解しよう ◁今回はココ
 ・Lesson1-5:文字列の連結と埋め込みを理解しよう
 ・Lesson1-6:文字列を操作しよう
 ・Lesson1-7:import文を理解しよう
 ・確認問題1-☆1:ランダムパスワードを生成しよう
Lesson2:制御構造編
Lesson3:関数編
Lesson4:コレクション編
Lesson5:オブジェクト指向編

<<前のページ

学習記事一覧

次のページ>>

Null安全性とは?|エラーを防ぐ基本知識

プログラミングにおけるエラーの多くは「Null参照」という、存在しないオブジェクトや値にアクセスすることで発生します。

特に、例外をキャッチできずにプログラムがクラッシュする原因となり、多くの開発者を悩ませてきました。

Kotlinはこの「Null参照問題」に対処するために、Null安全性 を強力にサポートしています。

本記事ではKotlinのNull安全性について学び、安全なコードの書き方を紹介します。

Nullの基礎を理解しよう|値が存在しない状態とは?

Nullとは「値が存在しない状態」を指します。

Javaなどでは、nullを誤って参照すると NullPointerException(NPE/ぬるぽ)が発生しますが、Kotlinではこれを未然に防ぐ仕組みが用意されています。

Kotlinでは「nullを許容する変数/定数」と「許容しない変数/定数」を明示的に区別します。

  • val name: String = "Kotlin" → Nullを許容しない(非Nullable)定数
  • val name: String? = null → Nullを許容する(Nullable)定数

このように型の定義時に?を付けることで、Nullableな(値がNullであってもエラーにならない)変数/定数として扱うことができます。

この明示的な区別がエラーの早期発見に役立ちます。

Null安全性を実現するKotlin構文一覧

Kotlinが提供するNull安全性を実現する構文をいくつか紹介します。

1. セーフコール(安全呼び出し)演算子(?

Null許容型の変数に何かを行う際、変数名の後ろに セーフコール演算子:「?」 をつけることで安全に値を操作できます。

lengthプロパティ を使用して、その変数に格納された文字列の長さ(文字数)を調べる例を見てみましょう

// lengthプロパティの使い方
val name: String = "tanaka"		// 非Nullable型の定数nameに文字列「Tanaka」を代入
val length_1: Int = name.length	// nameの文字数をlengthプロパティで取得し、定数length_1に代入
println(length_1)				// 取得した文字数を出力:6

// セーフコール演算子の使用例
val message: String? = null				// Null許容型の定数messageを定義し、nullを代入
val length_2: Int? = message?.length	// messageの文字数をlengthプロパティで取得し、定数length_2に代入
	// messageがnullでなければlengthプロパティを呼び、nullならそのままnullを返すために「?」をつける
	// messageがnullなので、length_2もnullになる
val length_3: Int? = message.length		// コンパイルエラー

このように、変数名の後ろにセーフコール演算子をつけることで、lengthのような変数を操作するプロパティなどを安全に呼び出せるようになります。

変数/定数を操作する際にそれがnullの可能性があるなら、セーフコール演算子をつけるものと覚えておきましょう。

またlengthプロパティについては Lesson1-6:文字列操作を理解しよう で詳しく学習しますが、ここでは「変数/定数の後ろにつけて文字数を取得するもの」とだけ覚えておけば十分です。

2. エルビス演算子(?:

エルビス演算子は 「ある値がnullなら、別の値を代入する」という使い方ができる簡潔な記述方法です。

記号は「?:」で、見た目が“エルビス・プレスリーの髪型”に似ていることからこの名前がついています。

val length: Int = text?.length ?: 0	// 定数lengthに定数textの文字数を代入
									// textがnullなら0を代入

3. 非Nullアサーション(!!

非Nullアサーション は、変数がnullでないと分かっている際にKotlinのnull安全を“無視”し、強制的にnullを非nullとして扱うための機能です。

通常、Kotlinではnullの可能性がある値に直接アクセスするとエラーになりますが、「この変数は絶対にnullではない」と断言して使う方法が「!!」です。

ただし、実際にnullだった場合は実行時エラー(NullPointerException)になるため、基本的には安全な設計で!!を使わずに済むようにしましょう。

val length: Int = nullableValue!!.length	//定数lengthに定数nullableValueの文字数を代入
// nullableValueがnullの場合、例外がスローされる

4. toIntOrNull()ので安全に型変換

通常のtoInt()は無効な文字列を数値に変換しようとするとエラーになりますすが、toIntOrNull() は変換できない場合にnullを返します。

val number: Int? = "123".toIntOrNull()  // 変数numberに文字列123を整数に変換して代入
val invalid: Int? = "abc".toIntOrNull() // 変数abcは整数に変換できないためnullを代入
val age: Int? = "text".toInt()			// エラー発生

このようにして、無効な入力を安全に処理することができます。

まとめ|Nullを理解し安全なKotlinコードを書こう

Null安全性はエラーを未然に防ぎ、安全なコードを書くための重要な機能です。

?!!、エルビス演算子、toIntOrNull()などの構文を活用することで、コードの安全性が向上します。

これらの機能は今後学ぶ内容ともつながっており、プログラムの理解を深める重要なステップとなります。

練習問題|Null安全性を使って安全に数値を扱おう

ユーザーが入力した値を安全に数値として扱うプログラムを作成しましょう。

このプログラムでは、ユーザーが入力した値を数値に変換し、変換が成功すればその値を表示します。

もし数値に変換できない場合は、0として処理を行います。またその結果に1を加えた値も出力しましょう。

この問題を通じて、KotlinのNull安全性を活用したプログラミングを学びます。

この問題の要件

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

  • readLine()を使用して、ユーザーから文字列として入力を受け取ること。
  • 入力値をtoIntOrNull()を用いて数値に変換すること。
    • 変換が成功した場合、その数値を利用すること。
    • 変換が失敗した場合、エルビス演算子(?:)を使って値を0に設定すること。
  • 入力値をもとに計算を行い、以下を表示すること:
    • 入力された数値
    • 入力された数値に1を加えた値

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

数値を入力してください(例: 123):
入力された数値:123  
入力された数値に1を足した結果:124
数値を入力してください(例: 123):
入力された数値:0  //abcと入力した場合
入力された数値に1を足した結果:1

この問題を解くヒント

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

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

正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)

1:main関数の定義
  □ 「数値を入力してください(例: 123):」と出力
  □ readLine関数で入力を受け取り、文字列型の変数inputに代入
  □ 変数inputをtoIntOrNullで整数型に変換し、numberに代入(変換できない場合はnull)
  □ エルビス演算子を使用して、numberがnullの場合は0をresultに代入
  □ 「入力された数値:」と出力
  □ 変数resultの値を出力
  □ 「入力された数値に1を足した結果:」と出力
  □ 変数resultに1を足した値を出力

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

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

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

fun main() {
    // ユーザーから数値の入力を受け取る
    println("数値を入力してください(例: 123):")
    val input = readLine() // 入力を受け取り文字列として保存します

    /*【穴埋め問題1】
    ここで入力された値を整数に変換し、変数numberに代入してください。数字でない場合はnullを代入してください。
    */

    /*【穴埋め問題2】
    ここでエルビス演算子を使って、numberがnullの場合は0を変数resultに代入してください。
    */

    // 結果を出力
    print("入力された数値:")
    println(result)
    print("入力された数値に1を足した結果:")
    println(result + 1)
}

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

この問題の解答と解説

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

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

Q
正解コード
// メイン関数 - Kotlinプログラムのエントリーポイント
fun main() {
    // ユーザーから数値の入力を受け取る
    println("数値を入力してください(例: 123):")
    val input = readLine() // 入力を受け取り文字列として保存します

    // 入力された値を整数に変換します。数字でない場合はnullが返されます。
    val number: Int? = input?.toIntOrNull()

    // Null安全性の確認 - nullの場合とnullでない場合で処理を分ける
    val result: Int = number ?: 0 // エルビス演算子を使用して、nullの場合は0を代入

    // 結果を出力
    print("入力された数値:")
    println(result)
    print("入力された数値に1を足した結果:")
    println(result + 1)
    /*
     * 説明:
     * 1. toIntOrNull()は文字列を整数に変換しますが、変換できない場合はnullを返します。
     * 2. ?:(エルビス演算子)は、変数がnullの場合にデフォルト値を設定します。
     * 3. このコードでは、nullの場合に0を代入しています。
     */
}
Q
正解コードの解説

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

メイン関数の定義

fun main() {
    println("数値を入力してください(例: 123):")

fun main(): Kotlinプログラムのエントリーポイントです。この関数の中にプログラム全体の処理が記述されています。

println(): 画面に文字を表示するための関数です。ここでは「数値を入力してください」というメッセージを表示しています。

ユーザー入力の取得

val input = readLine()

val input: 定数を宣言しています。valは再代入できない変数を定義するために使用します。

readLine(): ユーザーから文字列を入力するためのKotlin標準関数です。ここでは入力された値をinputに格納しています。

Null安全性を活用した値の変換

val number: Int? = input?.toIntOrNull()

Int?: この型は「Nullable型」と呼ばれ、値がnullになる可能性があることを示します。

toIntOrNull()は文字列を整数に変換する関数です。変換できない場合はnullを返します(例: 入力がabcの場合)。

?(安全呼び出し演算子)を使うことで、inputnullの場合でもエラーが発生せず、そのままnullを返します。

Null安全性を利用したデフォルト値の設定

val result: Int = number ?: 0

エルビス演算子(?:: Null安全性を実現するためのKotlinの演算子です。numbernullの場合、右側の値(ここでは0)が代入されます。

このコードではnumbernullならば0を、そうでなければnumberの値をresultに代入します。

結果の出力

    print("入力された数値:")
    println(result)
    print("入力された数値に1を足した結果:")
    println(result + 1)

結果を表示しています。

まとめ

このプログラムはKotlinの「Null安全性」を利用して、ユーザーが不正な値(例: 数字以外の文字列)を入力した場合でも、エラーが発生しないように設計されています。

特にtoIntOrNull()とエルビス演算子(?:)を活用することで、入力値の安全な処理を実現しています。

このコードを理解することで、Null安全性の基本的な使い方を学ぶことができるでしょう。

Kotlinのエラー回避機能は初心者にも扱いやすく、これを活用することで安全で堅牢なコードを書くスキルを身につけることができます。

ぜひ他の例でもtoIntOrNull()やエルビス演算子を試しながら学習を進めてみてください!

Q
サイト改善アンケート & ご指摘/ご質問

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

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

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

<<前のページ

学習記事一覧

次のページ>>

記事URLをコピーしました