Nil Mapの判定
CoddyのGOジャーニー「論理とフロー」セクションの一部。レッスン 28/68。
Goでは、mapはnilと呼ばれる特別な状態になることがあります。nilのmapは、基本的に初期化されておらず、メモリ上のどこも指していないmapです。この概念を理解することは非常に重要です。なぜなら、nilのmapにキーを追加しようとすると、プログラムがpanicを起こしてクラッシュするからです。
nil map がどのように発生し、どのように見えるかを説明します。
var myMap map[string]int
// この時点で myMap は nil ですmap 変数を初期化せずに Declare すると、Go は自動的に nil を設定します。nil の map から安全に読み取ることはできます(ゼロ値を returns します)が、そこに書き込もうとすると panic が発生します。
// これは安全です - 0を返します
value := myMap["key"]
// これはパニックします!
myMap["key"] = 42この問題を避けるには、map にキーを追加しようとする前に、map が nil かどうかを必ず確認してください。確認は簡単です。
if myMap == nil {
myMap = make(map[string]int)
}
myMap["key"] = 42 // これで安全ですこの単純なチェックにより、初期化されていない可能性のあるマップを扱う際にプログラムがクラッシュせず、コードの堅牢性と信頼性が向上します。
チャレンジ
簡単書き込み操作を実行する前に nil の map を確認することで、panic エラーを防ぐ安全な map 初期化システムを作成してください。この課題では、プログラムをクラッシュさせる可能性のある操作を実行する前に、map の状態を検証することがいかに重要かを示します。
次の 2 つの入力を受け取ります。
- operations の数を表す文字列(例:
"5") - カンマで区切られた operations を含む文字列。各 operation は、処理対象の map を指定します。
"check:[map_name]""init:[map_name]""add:[map_name]:[key]:[value]"
"check:scores,init:scores,add:scores:Alice:95,add:scores:Bob:87,check:grades"
タスクは次のとおりです。
map[string]int型の map 変数を 2 つ作成し、scoresおよびgradesという名前を付けます。初期化は行いません(これらは nil になります)。- 入力文字列の各 operation を sequentially 処理します。
"check"operations の場合:- 指定された map が nil かどうかを確認します。
- map が nil の場合は
"Map [map_name] is nil"を出力します。 - map が nil でない場合は
"Map [map_name] is initialized"を出力します。
"init"operations の場合:make(map[string]int)を使用して指定された map を初期化します。"Initialized map [map_name]"を出力します。
"add"operations の場合:- まず map が nil かどうかを確認します。
- map が nil の場合は
"Cannot add to nil map [map_name]"を出力します。 - map が nil でない場合は、key-value ペアを追加し、
"Added [key]:[value] to [map_name]"を出力します。
- 入力文字列を分割して operations を解析します。
- カンマで分割して個々の operations を取得します。
- 各 operation をコロンで分割し、operation の種類とパラメータを取得します。
addoperations では、value 文字列を integer に変換します。
- すべての operations の処理後、両方の map の Final state を表示します。
- 各 map が nil の場合:
"Final state - [map_name]: nil" - 各 map が初期化済みの場合:
"Final state - [map_name]: [count] entries"。ここで count は key-value ペアの数です。 - operations で使用された順序にかかわらず、最初に
scores、次にgradesを出力します。
- 各 map が nil の場合:
strconv package を使用して、add operations の value 文字列を integer に変換します。この課題では、書き込み operations の前に nil map を確認することで runtime panic を防ぎ、コードを堅牢で信頼性の高いものにする方法を示します。
自分で試してみよう
package main
import (
"fmt"
"strconv"
"strings"
)
func main() {
// 入力を読み取る
var numOpsStr string
var operationsStr string
fmt.Scanln(&numOpsStr)
fmt.Scanln(&operationsStr)
// 初期化せずにマップを宣言する(nilになる)
var scores map[string]int
var grades map[string]int
// カンマでoperationsを分割する
operations := strings.Split(operationsStr, ",")
// TODO: 以下にコードを書いてください
// 各operationを順番に処理する
// "check"、"init"、"add"のoperationsを処理する
// add operationsでは、strconv.Atoi()を使ってvalue文字列を整数に変換する
// 両方のmapsの最終状態を出力する
// mapsがnilか初期化済みかを確認し、それに応じて出力する
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
論理とフローのすべてのレッスン
自分で練習してみよう: Goオンラインコンパイラ