Menu
Coddy logo textTech

匿名の構造体

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},
}

匿名構造体には型名がないため、メソッドを定義したり、その型を他の場所で再利用したりすることはできません。これらは、一時的で局所的なデータのグループ化に使用してください。複数回参照するものについては、代わりに名前付き構造体型を定義してください。

challenge icon

チャレンジ

簡単

再利用可能な型を必要としない、一度限りのデータグループ化に匿名構造体が威力を発揮する場面を示す、簡単な設定システムを構築してみましょう。

コードは2つのファイルに分けて構成します:

  • config.go: サーバー名 (string)、ポート番号 (int)、デバッグモード (bool) をパラメータとして受け取る GetServerConfig という関数を作成します。この関数は、これら3つの値をフィールドとして持つ匿名構造体(NamePortDebug)を返す必要があります。この設定は1箇所でしか使用されないため、名前付きの型を定義する必要はありません。
  • main.go: 入力からサーバー設定値を読み取り、GetServerConfig 関数を呼び出して、設定の詳細を表示します。

以下の入力が提供されます:

  • 1行目: サーバー名
  • 2行目: ポート番号
  • 3行目: デバッグモード (true または false)

出力形式:

Server: [Name]
Port: [Port]
Debug: [Debug]

例えば、api-server8080true が与えられた場合、出力は以下のようになります:

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]
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン