構造体の中に構造体を埋め込む定義方法を理解しよう!

Go言語
この記事は約7分で読めます。
Go初学者
Go初学者

Go言語で構造体の中に構造体を埋め込むことができるって本当ですか?

この記事では構造体に構造体を埋め込む方法を理解できます!
  • 構造体を埋め込む定義を理解できる
  • 構造体を埋め込む動作をプログラムで確認できる

今回は、Go言語の構造体の機能で「構造体に構造体を埋め込む」という、ちょっとややこしい文章で申し訳ないのですが…でも、こういう機能なのです。

他のプログラミング言語では「継承」に近い機能と言えるでしょう。

では、プログラムで確認しながら「構造体に構造体を埋め込む」動きを理解していきましょう。

この記事では、構造体の基本的なことには触れていません。

当ブログ記事を参考にしてみてください。

もりぴ
この記事を書いた人

XHTML1.0時代にHTML&CSSを勉強した経験あり。無趣味だった私が2020年5月からプログラミング学習を開始し現在も挫折せずに趣味で学習を楽しんでいる51歳。プログラミングの楽しさをブログを通してお伝えしていきます。

もりぴをフォローする

Go言語の構造体を埋め込むとは?

オブジェクト指向プログラミングの三大要素のひとつである「継承」ですが、Go言語では継承の機能がありません。

ですが、継承に近い機能として「構造体に構造体を埋め込む」ことができます。

構造体を埋め込む定義

「構造体に構造体を埋め込む」には下記のように定義します。

// 構造体に構造体を埋め込む定義
package main

// 埋め込む構造体
type 構造体の型名 struct {
    フィールド名1 型
    フィールド名2 型
         ・
         ・
         ・
    フィールド名x 型
}

// 構造体を埋め込む(標準的な方法)
type 構造体の型名 struct {
    構造体のフィールド名 構造体の型
    フィールド名1 型
    フィールド名2 型
         ・
         ・
         ・
    フィールド名x 型
}

// 埋め込んだ構造体の型は省略できる
type 構造体の型名 struct {
    構造体のフィールド名
    フィールド名1 型
    フィールド名2 型
         ・
         ・
         ・
    フィールド名x 型
}

func main() {

}

構造体を埋め込む標準的な定義をプログラムで確認

それでは、先程紹介した記述方法で、実際にプログラムを確認していきましょう。

もりぴ
もりぴ

今回はロールプレイングゲームのモンスターを設定してみます。

// 構造体を埋め込む標準的な定義
package main

import "fmt"

type Monster struct {
    Name      string
    Attribute string
}

// 構造体を埋め込む
type MonsterData struct {
    Monster Monster
    Hp      int
    Mp      int
    attack  int
    defense int
}

func main() {
    // 構造体を初期化
    slimeData := MonsterData{
	Monster: Monster{
		Name:      "スライム",
		Attribute: "スライム属",
	},
	Hp:      80,
	Mp:      0,
	attack:  10,
	defense: 10,
    }
    // slimeDataを出力
    fmt.Println(slimeData)

   // 埋め込んだ構造体(MonsterData)の値を取り出す
   fmt.Println(slimeData.Monster)

    // Nameの値を取り出す
    fmt.Println(slimeData.Monster.Name)
}
// 出力結果
$ go run main.go 
{{スライム スライム属} 80 0 10 10}
{スライム スライム属}
スライム

{{スライム スライム属} 80 0 10 10} 構造体の出力結果を見てみると、構造体の中に {} で囲まれている部分が埋め込んだ構造体のデータになります。

値の取り出しには . を使って、目的の値まで掘り下げていくイメージになります。

型を省略して構造体を埋め込む定義をプログラムで確認

構造体を埋め込む時に、型を省略することができます。

型を省略して構造体を埋め込む定義をプログラムで確認で実際に確認してみましょう。

// 構造体を埋め込む標準的な定義
package main

import "fmt"

type Monster struct {
    Name      string
    Attribute string
}

// 埋め込んだ構造体の型は省略できる
type MonsterData struct {
    Monster  // 型を省略している
    Hp      int
    Mp      int
    attack  int
    defense int
}

func main() {
    // Monsterを初期化
    metalslime := Monster{
	Name:      "メタルスライム",
	Attribute: "メタルスライム属",
    }
    // 変数metalslimeを構造体に埋め込んで初期化
    metalslimeData := MonsterData{
	Monster: metalslime,
	Hp:      10000,
	Mp:      300,
	attack:  100,
	defense: 20000,
    }
    fmt.Println(metalslimeData)
	
    // metalslimeDataの名前を取り出す
    fmt.Println(metalslimeData.Monster.Name)
    
    // 埋め込んだ構造体の型を省略した場合のみ型を省略できる
    fmt.Println(metalslimeData.Name)
}
// 出力結果
$ go run main.go 
{{メタルスライム メタルスライム属} 10000 300 100 20000}
メタルスライム
メタルスライム

今回は埋め込む先の構造体 Monster を先に初期化して埋め込んでいます。

もりぴ
もりぴ

コード少し見やすくなりますね!

今回は構造体を埋め込む時に型を省略していますが、値を取り出すところで気になるところがありませんか?

Go初学者
Go初学者

あれ?fmt.Println(metalslimeData.Name)型が省略されてますね。

ここに違いがあり、これは型を省略して構造体を埋め込んだ時のみ使用できます。

もし、型を省略せずに fmt.Println(metalslimeData.Name) のように値を取得しようとすると…

// 出力結果
$ go run main.go 
# command-line-arguments
./main.go:63:28: metalslimeData.Name undefined (type MonsterData has no field or method Name)

「 metalslimeData.Name が未定義です」「タイプ MonsterData にはフィールドまたはメソッド名がありません」というエラーが出力されます。

【まとめ】Go言語で構造体を埋め込むには

今回は構造体を埋め込む機能と値の取り出しについて紹介してきました。

それでは、まとめにはいります。

構造体を埋め込む定義方法

構造体に構造体を埋め込むには2種類の方法がありました。

// 構造体に構造体を埋め込む定義
package main

// 埋め込む構造体
type 構造体の型名 struct {
    フィールド名1 型
    フィールド名2 型
         ・
         ・
         ・
    フィールド名x 型
}

// 1.構造体を埋め込む(標準的な方法)
type 構造体の型名 struct {
    構造体のフィールド名 構造体の型
    フィールド名1 型
    フィールド名2 型
         ・
         ・
         ・
    フィールド名x 型
}

// 2.埋め込んだ構造体の型は省略できる
type 構造体の型名 struct {
    構造体のフィールド名
    フィールド名1 型
    フィールド名2 型
         ・
         ・
         ・
    フィールド名x 型
}
構造体を埋め込む定義以外で押さえておくべきこと!
  • 型を省略して構造体を埋め込んだ時は、値を取り出す際に型を省略して取り出すことができる

以上です。

今回のプログラムは機能を理解するために単純なプログラムでしたが、構造体の埋め込みは活用することが多い機能です。

実際にいろんなパターンで、あなたがコードを書いて動きを確かめてみましょう。

comment

タイトルとURLをコピーしました