Menu
Coddy logo textTech

構造体のネスト

CoddyのGOジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 16/107。

ネストされた構造体とは、フィールドの1つとして別の名前付き構造体を含む構造体のことです。これにより、小さく再利用可能な型を組み合わせることで、複雑で階層的なデータをモデル化できます。

type Address struct {
    Street string
    City   string
    ZIP    string
}

type Person struct {
    Name    string
    Age     int
    Address Address  // ネストされた構造体
}

ネストされた構造体のフィールドにアクセスするには、フィールド名をドットで繋ぎます。

p := Person{
    Name: "Alice",
    Age:  30,
    Address: Address{
        Street: "123 Main St",
        City:   "Boston",
        ZIP:    "02101",
    },
}

fmt.Println(p.Address.City) // Boston

ネスト(入れ子)はコードの再利用を促進します。Address型は、フィールドを重複させることなく、PersonCompanyOrderなどの複数の構造体で使用できます。このアプローチは、エンティティが他のエンティティを含むという現実世界の概念を反映しています。

type Company struct {
    Name      string
    Employees int
    Address   Address  // 同じ Address 型を再利用
}

構造体は複数レベルの深さまでネストできますが、階層を浅く保つことで可読性が向上します。ネストされた構造体は、Goでオブジェクト指向のデータモデルを構築するための基本です。

challenge icon

チャレンジ

簡単

現実世界の階層構造をモデル化する際に、ネストされた構造体(nested structs)がどのように役立つかを示す従業員管理システムを構築しましょう。従業員が部署に所属し、部署が場所情報を持つという構造を作成します。

コードを2つのファイルに分けて整理します:

  • models.go: 連携して動作する3つの構造体を定義します:
    • Building (string) と Floor (int) フィールドを持つ Location
    • Name (string) とネストされた Location フィールドを持つ Department
    • ID (int)、Name (string)、およびネストされた Department フィールドを持つ Employee
  • main.go: 入力から従業員情報を読み取り、適切にネストされた構造体を持つ Employee を作成し、ネストされた構造を通じてフィールドにアクセスして完全な従業員プロファイルを表示します。

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

  • 1行目: 従業員ID(整数)
  • 2行目: 従業員名
  • 3行目: 部署名
  • 4行目: 建物名
  • 5行目: 階数(整数)

出力形式:

Employee: [Name] (ID: [ID])
Department: [DepartmentName]
Location: [Building], Floor [Floor]

例えば、101Alice ChenEngineeringTower A5 が与えられた場合、出力は以下のようになります:

Employee: Alice Chen (ID: 101)
Department: Engineering
Location: Tower A, Floor 5

ドット記法を使用して構造体の階層を連鎖させ、ネストされたフィールドにアクセスします(例:employee.Department.Location.Building)。

チートシート

入れ子になった構造体(nested struct)とは、フィールドの1つとして別の名前付き構造体を含む構造体のことで、より小さく再利用可能な型を組み合わせることで階層的なデータをモデル化できます。

入れ子になった構造体の定義

type Address struct {
    Street string
    City   string
    ZIP    string
}

type Person struct {
    Name    string
    Age     int
    Address Address  // 入れ子になった構造体
}

入れ子になったフィールドへのアクセス

ドット記法を使用して、構造体の階層を辿ります:

p := Person{
    Name: "Alice",
    Age:  30,
    Address: Address{
        Street: "123 Main St",
        City:   "Boston",
        ZIP:    "02101",
    },
}

fmt.Println(p.Address.City) // Boston

入れ子になった構造体の再利用

同じ入れ子になった構造体型を、複数の親構造体で再利用できます:

type Company struct {
    Name      string
    Employees int
    Address   Address  // 同じAddress型を再利用
}

入れ子になった構造体はコードの再利用を促進し、エンティティが他のエンティティを含むという現実世界の概念を反映します。構造体は何段階にも深く入れ子にすることができますが、階層を浅く保つことで可読性が向上します。

自分で試してみよう

package main

import "fmt"

func main() {
	// 従業員情報を読み込む
	var id int
	var name string
	var deptName string
	var building string
	var floor int

	fmt.Scanln(&id)
	fmt.Scanln(&name)
	fmt.Scanln(&deptName)
	fmt.Scanln(&building)
	fmt.Scanln(&floor)

	// TODO: 適切にネストされた構造体を使用してEmployeeを作成する
	// models.goのLocation、Department、Employee構造体を使用する
	// 入力値ですべてのネストされたフィールドを初期化する

	// TODO: 次の形式で従業員プロファイルを出力する:
	// Employee: [Name] (ID: [ID])
	// Department: [DepartmentName]
	// Location: [Building], Floor [Floor]
	// ドット記法を使用してネストされたフィールドにアクセスする (例: employee.Department.Location.Building)
}
quiz icon腕試し

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

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