匿名の構造体
CoddyのGOジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 15/107。
匿名構造体は、名前付きの型を持たない構造体です。typeキーワードを使用せずに、その構造の定義とインスタンスの作成を1つのステップで行います。
person := struct {
Name string
Age int
}{
Name: "Alice",
Age: 30,
}これは、再利用可能な型を宣言せずに、構造体の値を直接作成します。匿名構造体は、コードの他の場所で使用されない、一時的な使い捨てのデータ構造が必要な場合に便利です。
一般的なユースケースは、単一の関数またはテストのために関連するデータをグループ化することです。
config := struct {
Host string
Port int
}{
Host: "localhost",
Port: 8080,
}
fmt.Println(config.Host) // localhost匿名構造体は、各テストケースが固有のフィールドを持つテーブル駆動テストでもよく使われます。
tests := []struct {
input int
expected int
}{
{1, 2},
{5, 10},
}匿名構造体には型名がないため、メソッドを定義したり、その型を他の場所で再利用したりすることはできません。これらは、一時的で局所的なデータのグループ化に使用してください。複数回参照するものについては、代わりに名前付き構造体型を定義してください。
チャレンジ
簡単再利用可能な型を必要としない、一度限りのデータグループ化に匿名構造体が威力を発揮する場面を示す、簡単な設定システムを構築してみましょう。
コードは2つのファイルに分けて構成します:
config.go: サーバー名 (string)、ポート番号 (int)、デバッグモード (bool) をパラメータとして受け取るGetServerConfigという関数を作成します。この関数は、これら3つの値をフィールドとして持つ匿名構造体(Name、Port、Debug)を返す必要があります。この設定は1箇所でしか使用されないため、名前付きの型を定義する必要はありません。main.go: 入力からサーバー設定値を読み取り、GetServerConfig関数を呼び出して、設定の詳細を表示します。
以下の入力が提供されます:
- 1行目: サーバー名
- 2行目: ポート番号
- 3行目: デバッグモード (
trueまたはfalse)
出力形式:
Server: [Name]
Port: [Port]
Debug: [Debug]例えば、api-server、8080、true が与えられた場合、出力は以下のようになります:
Server: api-server
Port: 8080
Debug: true匿名構造体を使用することで、一度しか使われない型でコードベースを煩雑にすることなく、グループ化されたデータを返せることに注目してください。
チートシート
匿名構造体(anonymous struct)は、名前付きの型を持たない構造体であり、typeキーワードを使用せずに、定義とインスタンス化を一段階で行います。
person := struct {
Name string
Age int
}{
Name: "Alice",
Age: 30,
}匿名構造体は、コード内の他の場所で再利用されない、一度限りのデータ構造に便利です。
一般的なユースケースには、単一の関数内で関連するデータをグループ化することが含まれます。
config := struct {
Host string
Port int
}{
Host: "localhost",
Port: 8080,
}
fmt.Println(config.Host) // localhostまた、テーブル駆動テスト(table-driven tests)でも使用されます。
tests := []struct {
input int
expected int
}{
{1, 2},
{5, 10},
}匿名構造体にはメソッドを定義したり、型として再利用したりすることはできません。一時的で局所的なデータのグループ化に使用してください。複数回参照される型については、代わりに名前付き構造体を定義してください。
関数は匿名構造体を返すこともできます。
func GetConfig() struct {
Name string
Port int
} {
return struct {
Name string
Port int
}{
Name: "server",
Port: 8080,
}
}自分で試してみよう
package main
import (
"fmt"
)
func main() {
// 入力値を読み取る
var name string
var port int
var debug bool
fmt.Scanln(&name)
fmt.Scanln(&port)
fmt.Scanln(&debug)
// TODO: 入力値を使用して GetServerConfig を呼び出し、
// 返された無名構造体を保存する
// TODO: 必要な形式で設定を出力する:
// Server: [Name]
// Port: [Port]
// Debug: [Debug]
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
1Go オブジェクト指向の基礎
外部ファイルGo ワークスペースとモジュールパッケージとインポート公開された名前と非公開の名前Go におけるオブジェクト指向入門クラスとしての構造体構造体へのメソッド定義ポインタレシーバと値レシーバ構造体の初期化コンストラクタ関数まとめ:簡易計算機8エラー処理とOOP
error インターフェースカスタムエラー型エラーラッピング (fmt.Errorf)センチネルエラーerrors.Is() と errors.As()Panic、Defer、Recover復習 - ファイルパーサー