ゼロ値とデフォルト値
CoddyのGOジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 17/107。
Goでは、すべての変数にゼロ値(明示的な初期化なしに変数を宣言したときに割り当てられるデフォルト値)があります。初期化されていないフィールドは自動的にこれらのデフォルト値を受け取るため、構造体を扱う際にはゼロ値を理解することが不可欠です。
各型には独自のゼロ値があります:
| 型 | ゼロ値 |
|---|---|
| int, float64 | 0 |
| string | "" (空文字列) |
| bool | false |
| pointer, slice, map | nil |
構造体を作成するとき、明示的に設定しなかったフィールドにはその型のゼロ値が割り当てられます。
type User struct {
Name string
Age int
Active bool
}
func main() {
var u User
fmt.Println(u.Name) // "" (空の文字列)
fmt.Println(u.Age) // 0
fmt.Println(u.Active) // false
}これは部分的な初期化にも当てはまります。指定したフィールドのみがカスタム値を取得します。
u := User{Name: "Alice"}
fmt.Println(u.Age) // 0
fmt.Println(u.Active) // false
ゼロ値により、構造体は明示的な初期化なしですぐに使用可能になります。しかし、スライスやマップのような参照型には注意してください。それらのゼロ値は nil であり、初期化せずに使用しようとするとランタイムパニックを引き起こす可能性があります。
チャレンジ
簡単Goにおけるゼロ値の仕組みを実演するプレイヤープロフィールシステムを構築しましょう。一部のフィールドは明示的に設定し、他のフィールドはデフォルトのゼロ値に依存するゲームプロフィールを作成します。
コードは2つのファイルに分けて構成します:
player.go: 以下のフィールドを持つPlayer構造体を定義します:Username(string)、Level(int)、Score(int)、IsPremium(bool)、およびGuildName(string)。また、プレイヤーのすべての情報を表示するフォーマット済み文字列を返すDisplayProfileメソッドを作成します。main.go: 入力からユーザー名を読み取り、部分的な初期化(Usernameフィールドのみを設定)を使用して Player を作成します。その後、完全なプロフィールを表示して、設定されていないフィールドに Go がどのようにゼロ値を埋めるかを確認します。
以下の入力が提供されます:
- 1行目: プレイヤーのユーザー名
DisplayProfile メソッドは、以下の正確な形式で文字列を返す必要があります:
Username: [Username]
Level: [Level]
Score: [Score]
Premium: [IsPremium]
Guild: [GuildName]例えば、ユーザー名が ShadowKnight の場合、出力にはユーザー名とともに、初期化されていないフィールドのすべてのゼロ値が表示されるはずです:
Username: ShadowKnight
Level: 0
Score: 0
Premium: false
Guild: Guild フィールドのコロンの後に何も表示されていないことに注目してください。これが空文字列のゼロ値です。このチャレンジは、明示的な値を指定しなかった場合に Go が各型に何を割り当てるかを正確に理解するのに役立ちます。
チートシート
Goでは、すべての変数にゼロ値(明示的な初期化なしで変数を宣言したときに割り当てられるデフォルト値)があります。
各型には独自のゼロ値があります:
| 型 | ゼロ値 |
|---|---|
| int, float64 | 0 |
| string | "" (空の文字列) |
| bool | false |
| pointer, slice, map | nil |
構造体を作成するとき、明示的に設定しなかったフィールドにはそのゼロ値が割り当てられます:
type User struct {
Name string
Age int
Active bool
}
func main() {
var u User
fmt.Println(u.Name) // "" (空の文字列)
fmt.Println(u.Age) // 0
fmt.Println(u.Active) // false
}部分的な初期化 — 指定されたフィールドのみがカスタム値を取得します:
u := User{Name: "Alice"}
fmt.Println(u.Age) // 0
fmt.Println(u.Active) // falseゼロ値により、明示的な初期化なしで構造体をすぐに使用できるようになります。スライスやマップのような参照型には注意してください。それらのゼロ値は nil であり、初期化せずに使用するとランタイムパニックを引き起こす可能性があります。
自分で試してみよう
package main
import (
"fmt"
)
func main() {
// 入力から username を読み込む
var username string
fmt.Scanln(&username)
// TODO: 部分初期化を使用して Player を作成する
// Username フィールドのみを設定し、他のフィールドにはゼロ値を使用させる
// TODO: DisplayProfile メソッドを使用してプレイヤーのプロファイルを表示する
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
1Go オブジェクト指向の基礎
外部ファイルGo ワークスペースとモジュールパッケージとインポート公開された名前と非公開の名前Go におけるオブジェクト指向入門クラスとしての構造体構造体へのメソッド定義ポインタレシーバと値レシーバ構造体の初期化コンストラクタ関数まとめ:簡易計算機8エラー処理とOOP
error インターフェースカスタムエラー型エラーラッピング (fmt.Errorf)センチネルエラーerrors.Is() と errors.As()Panic、Defer、Recover復習 - ファイルパーサー