カテゴリ: Go言語 更新日: 2026/02/22

Go言語の構造体の埋め込み(匿名フィールド)の使い方をやさしく解説!

Go言語の構造体の埋め込み(匿名フィールド)の使い方
Go言語の構造体の埋め込み(匿名フィールド)の使い方

先生と生徒の会話形式で理解しよう

生徒

「Go言語には構造体の『埋め込み』とか『匿名フィールド』っていう仕組みがあると聞いたのですが、何ができるんですか?」

先生

「構造体の埋め込みを使うと、ある構造体の機能をほかの構造体で“継承っぽく”使えるんですよ。Goでは継承は使わないけれど、似たことができるんです。」

生徒

「継承っぽいってどういうことですか?詳しく教えてください!」

先生

「それでは、構造体の埋め込みの仕組みを、初心者でもわかるように順に説明しますね!」

1. 匿名フィールド(埋め込み)とは?

1. 匿名フィールド(埋め込み)とは?
1. 匿名フィールド(埋め込み)とは?

Go言語の匿名フィールド(埋め込み)は、構造体の中に別の構造体を“名前なしで”そのまま入れ込む仕組みです。通常のフィールドのように「フィールド名: 型」と書かず、型だけを書くことで利用できます。これによって、埋め込んだ構造体が持つフィールドやメソッドを、まるで自分のもののように扱えるようになります。

イメージとしては、「バッグの中に小物ポーチをそのまま入れて、ポーチの中身をバッグの中身として扱える」ような感覚です。ポーチのファスナーを毎回開けなくても、中身に直接アクセスできるイメージですね。継承のように見えますが、Goではあくまで“埋め込まれて共有している”だけなので、とてもシンプルです。

まずは、匿名フィールドを使った最小の例を見てみましょう。


package main

import "fmt"

type Info struct {
    ID int
}

type User struct {
    Info // 匿名フィールドとして埋め込み
}

func main() {
    u := User{Info: Info{ID: 10}}
    fmt.Println("ユーザーID:", u.ID) // Info.ID を直接参照できる
}

この例のように、UserInfoを埋め込むだけで、u.IDという形で直接アクセスできるようになります。初心者の方でもすぐに「なるほど、こういう便利さがあるのか」と実感できるはずです。

2. 埋め込み構造体の書き方

2. 埋め込み構造体の書き方
2. 埋め込み構造体の書き方

埋め込み構造体の基本はとてもシンプルで、「フィールド名を書かずに型だけを書く」だけです。Go言語では、この書き方をすることで、その型の持つフィールドやメソッドを“自分の構造体のもの”として扱えるようになります。初心者にとっては難しそうに見えますが、一度動きを見ると直感的で理解しやすい仕組みです。

まずは典型的な例を見てみましょう。動物を表すAnimal構造体を、犬を表すDog構造体に埋め込みます。


type Animal struct {
    Name string
}

type Dog struct {
    Animal  // Animal構造体を埋め込み
    Breed  string
}

この書き方をすると、Dog の中に Animal のフィールドが“直接”存在しているように扱えます。つまり、Dog構造体を使うときに、d.Animal.Nameと書かず、d.Nameとそのまま使えるようになります。

簡単な動作例も見てみましょう。


package main

import "fmt"

type Animal struct {
    Name string
}

type Dog struct {
    Animal
    Breed string
}

func main() {
    d := Dog{
        Animal: Animal{Name: "モモ"},
        Breed:  "コーギー",
    }

    fmt.Println("犬の名前:", d.Name)     // Animal.Name を直接参照
    fmt.Println("犬の種類:", d.Breed)
}

このように、構造体の埋め込みを使うと「別の構造体の機能を簡単に取り込む」ことができ、コードの重複を減らす助けになります。慣れるととても便利なテクニックなので、まずは小さな例から触れて感覚をつかんでみてください。

3. 埋め込みの簡単な例

3. 埋め込みの簡単な例
3. 埋め込みの簡単な例

ここまでで「構造体を埋め込める」という話をしましたが、実際にコードとして動かしてみるとイメージがつかみやすくなります。ここでは、動物を表す Animal 構造体を、犬を表す Dog 構造体に埋め込み、フィールドやメソッドにどのようにアクセスできるかを見ていきましょう。

まずは、名前を持つ Animal と、その Animal を埋め込んだ Dog を用意し、画面に情報を表示してみます。


package main

import "fmt"

// Animal は「名前」を持つ生き物を表す構造体です。
type Animal struct {
    Name string
}

// Speak は Animal が鳴く様子を表示するメソッドです。
func (a Animal) Speak() {
    fmt.Println(a.Name, "が鳴いています")
}

// Dog は Animal を埋め込み、さらに犬種(Breed)も持つ構造体です。
type Dog struct {
    Animal
    Breed string
}

func main() {
    // Animal を埋め込んだ Dog の値を作成
    d := Dog{
        Animal: Animal{Name: "ポチ"},
        Breed:  "柴犬",
    }

    // 埋め込まれた Animal の Name に直接アクセス
    fmt.Println("名前:", d.Name)

    // 埋め込まれた Animal のメソッドもそのまま呼び出せる
    d.Speak()

    // Dog 独自のフィールド Breed にもアクセス
    fmt.Println("種類:", d.Breed)
}

実行結果:


名前: ポチ
ポチ が鳴いています
種類: 柴犬

ここでのポイントは、d.Animal.Name と書かなくても、d.Name として直接アクセスできているところです。また、Animal に定義した Speak メソッドも、d.Speak() とそのまま呼び出せています。まるで NameSpeak が最初から Dog の一部として用意されているかのように振る舞ってくれるため、コードの見た目がすっきりし、Go言語の構造体設計がぐっと扱いやすくなります。

4. 埋め込みのメリットと注意点

4. 埋め込みのメリットと注意点
4. 埋め込みのメリットと注意点
  • コードの再利用:Animal構造体に定義をまとめておけば、ほかの構造体でも使える。
  • 読みやすさアップ:Dog構造体からNameSpeakに直接アクセスでき、コードがシンプル。
  • 注意点:もし埋め込み先と埋め込み元で同じフィールド名やメソッド名を定義すると、どちらを使うか曖昧になります。

5. 同名フィールドがあるときはどう書く?

5. 同名フィールドがあるときはどう書く?
5. 同名フィールドがあるときはどう書く?

例えば、Dog構造体にNameフィールドを直接追加すると、どちらのNameを参照するか明示が必要になります。


type Dog struct {
    Animal
    Name string  // 同じNameというフィールド
}

このとき、d.NameDog.Nameを指し、d.Animal.Nameで埋め込み元のNameにアクセスできます。

6. メソッドの埋め込み利用

6. メソッドの埋め込み利用
6. メソッドの埋め込み利用

構造体にメソッドを定義しておけば、埋め込み先でもそのメソッドを呼び出せます。


func (a Animal) Move() {
    fmt.Println(a.Name, "が歩いています")
}

func main() {
    d := Dog{Animal: Animal{Name: "タロウ"}, Breed: "雑種"}
    d.Move()  // Animalのメソッドをそのまま実行
}

このように、電話にカメラを搭載して「写真を撮る」という機能がそのまま使えるイメージです!

7. 匿名フィールドは組み込み型にも使える?

7. 匿名フィールドは組み込み型にも使える?
7. 匿名フィールドは組み込み型にも使える?

はい、例えばtime.Timeを埋め込んで、構造体に時間操作機能を追加することもできます。


type Event struct {
    time.Time
    Title string
}

こうすると、EventTimeのメソッド(たとえばYear())が使えます。

まとめ

まとめ
まとめ

Go言語における構造体の埋め込み(匿名フィールド)は、オブジェクト指向言語における「継承」に似た役割を果たしながらも、Go言語らしいシンプルで直感的な書き方を実現する仕組みです。この記事を通して、匿名フィールドを使うことでコードを再利用しやすくなり、可読性が高まることを学びました。たとえば、Animal構造体をDog構造体に埋め込むことで、NameSpeakメソッドを直接利用できるのはとても便利です。

また、構造体埋め込みを利用することで、メソッドの再利用共通処理の共有が可能になり、コードの重複を避けられる点も大きなメリットでした。特に複数の構造体で同じ性質を持たせたいときに役立ちます。さらに、標準ライブラリのtime.Timeを埋め込む例のように、既存の便利な機能を組み込んで拡張できる点もGoならではの強力な機能です。

ただし、注意点として同名フィールドやメソッドの衝突があります。たとえば、Dog構造体にNameを直接定義した場合、d.NameはDogのフィールドを参照し、d.Animal.Nameを明示しなければならなくなります。これは大規模開発やチーム開発で特に気をつけたい部分です。

まとめると、Go言語の構造体埋め込みは「継承の代わりにコードをシンプルに再利用するためのテクニック」であり、Go言語らしい考え方を理解するうえで欠かせない基本知識です。今後、API設計や大規模なプログラム開発を行うときに必ず役立つ概念なので、初心者のうちからしっかり身につけておきましょう。

サンプルプログラムでまとめを確認


package main

import (
    "fmt"
    "time"
)

type Animal struct {
    Name string
}

func (a Animal) Speak() {
    fmt.Println(a.Name, "が鳴いています")
}

type Dog struct {
    Animal
    Breed string
}

type Event struct {
    time.Time
    Title string
}

func main() {
    d := Dog{
        Animal: Animal{Name: "ハチ"},
        Breed:  "秋田犬",
    }
    d.Speak()
    fmt.Println("犬種:", d.Breed)

    e := Event{
        Time:  time.Now(),
        Title: "勉強会",
    }
    fmt.Println("イベント:", e.Title, "年:", e.Year())
}

上記のプログラムでは、Animalを埋め込んだDogがSpeak()を呼び出せること、さらにtime.Timeを埋め込んだEventがYear()を使えることを確認できます。このように埋め込みは実用性が高く、日常的に活用できる便利な仕組みです。

先生と生徒の振り返り会話

生徒

「Go言語の構造体の埋め込みって、やっぱりすごく便利ですね!継承みたいに使えるけど、シンプルでわかりやすいです。」

先生

「そうですね。Goは継承を持たない代わりに、埋め込みで機能を柔軟に再利用できるんです。特に、標準ライブラリの構造体をそのまま活用できるのは大きな魅力ですよ。」

生徒

「同じフィールド名があるときに注意が必要だと学びました。d.Named.Animal.Nameを区別して使うのは重要ですね。」

先生

「その通りです。曖昧さを避けるために、コードを書くときやレビューするときには必ず意識しておくと良いですよ。」

生徒

「これからは埋め込みを使って、コードの再利用性を高めながら効率的にプログラムを書いていきたいです!」

先生

「素晴らしい心がけですね。埋め込みを理解すれば、Go言語での開発がもっと楽しく効率的になりますよ。」

この記事のまとめ部分の全角文字数:2832文字

Go言語を基礎からスッキリ学びたい人や、 文法だけでなく「実用的な使い方」まで押さえたい人には、 定番の入門書がこちらです。

基礎からわかるGo言語をAmazonで見る

※ Amazon広告リンク

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

Go言語の構造体における匿名フィールドや埋め込みとは具体的にどんな仕組みですか?

Go言語の構造体における匿名フィールドや埋め込みとは、フィールド名を省略して型だけを記述することで、他の構造体をまるごと組み込める仕組みです。これにより継承のように機能を再利用でき、コードの可読性や再利用性が向上します。

Go言語では継承がないと聞きましたが、埋め込みを使うことでオブジェクト指向的な継承のようなことはできますか?

はい、Go言語には継承の仕組みはありませんが、構造体の埋め込みを利用することで「継承っぽい」動きを実現できます。親にあたる構造体のフィールドやメソッドを、子にあたる構造体から直接呼び出せます。

この記事の質問と回答部分の全角文字数:2864文字

関連セミナーのご案内

【超入門】ゼロから始めるGo言語プログラミング:最速で「動くアプリ」を作るマンツーマン指導

「プログラミングの仕組み」が根本からわかる。Go言語でバックエンド開発の第一歩を。

本講座を受講することで、単なる文法の暗記ではなく、「プログラムがコンピュータの中でどう動いているか」という本質的な理解につながります。シンプルながら強力なGo言語(Golang)を通じて、現代のバックエンドエンジニアに求められる基礎体力を最短距離で身につけます。

具体的な開発内容と環境

【つくるもの】
ターミナル(黒い画面)上で動作する「対話型計算プログラム」や、データを整理して表示する「ミニ・ツール」をゼロから作成します。自分の書いたコードが形になる感動を体験してください。

【開発環境】
プロの現場でシェアNo.1のVisual Studio Code (VS Code)を使用します。インストールから日本語化、Go言語用の拡張機能設定まで、現場基準の環境を一緒に構築します。

この60分で得られる3つの理解

1. 環境構築の完全な理解

「なぜ動くのか」という設定の仕組みを理解し、今後の独学で詰まらない土台を作ります。

2. Go言語の基本構造(変数・型)

データの種類やメモリの概念など、他言語にも通じるプログラミングの本質を学びます。

3. 読みやすいコードの書き方

ただ動くだけでなく、誰が見ても分かりやすい「綺麗なコード」を書くための考え方を伝授します。

※本講座は、将来的にバックエンドエンジニアクラウドインフラに興味がある未経験者のためのエントリー講座です。マンツーマン形式により、あなたの理解度に合わせて進行します。

セミナー画像

初めてのGo言語を一緒に学びましょう!

関連記事:
カテゴリの一覧へ
新着記事
New1
Go言語
Go言語のwhile的なforループの使い方!条件式ループの基本を解説
New2
Go言語
Go言語プログラムの実行方法まとめ!VSCode・ターミナルでの実行手順を解説
New3
Swift
Swift意味とは?プログラミング言語・金融・鳥の違いを徹底解説
New4
Swift
Swift 戻り値の扱い方と複数戻り値の返し方|初心者でも分かる関数の基本
人気記事
No.1
Java&Spring記事人気No1
Go言語
Go言語でリダイレクト処理を行う方法(http.Redirect)を初心者向けに解説
No.2
Java&Spring記事人気No2
Swift
Swift開発環境の構築方法を徹底解説!Xcode・Windows・Linux対応
No.3
Java&Spring記事人気No3
Kotlin
Android Studioのインストール手順と初期設定を初心者向けに完全解説!
No.4
Java&Spring記事人気No4
Kotlin
Gradleファイル(build.gradle.kts)の書き方と役割をやさしく解説!Kotlin初心者向け完全ガイド
No.5
Java&Spring記事人気No5
Go言語
Go言語のgo.modファイル完全ガイド!初心者でもわかる仕組みと書き方
No.6
Java&Spring記事人気No6
Swift
Swift Playgroundの使い方を完全解説!初心者に最適な学習環境の始め方
No.7
Java&Spring記事人気No7
Go言語
Go言語で条件式を1行で書くコツ!三項演算子の代替と短縮記法
No.8
Java&Spring記事人気No8
Kotlin
Kotlinの演算子一覧と使い方!算術・比較・論理演算子の基本を解説