サイト名変更・お引越しのお知らせ

Go言語の構造体(struct)の基本を解説

Go言語の構造体の基本について解説します。

構造体は、簡単にいうと複数の任意の型をまとめたものです。

Go言語を扱うにあたって非常に重要なので、理解して使えるようになりましょう。

この記事でわかること
  • Go言語の構造体の基本がわかる

バージョン
  • Go 1.17

定義方法

構造体を定義するときは、type 構造体名 struct {}のように定義します。

構造体を定義

type Dog struct {
	name string
	age  int
}

メモ

構造体は、値型の1つです。

構造体を定義すると、構造体に定義されているフィールドのメモリ領域が確保され、型ごとに初期値が設定されます。

初期化

初期化をする方法は主に2つあるのでそれぞれ解説します。

変数を定義し代入する方法

type Dog struct {
	name string
	age  int
}

func main() {
  var dog Dog
  dog.name = "ポチ"
  dog.age = 5
  fmt.Println(dog.name, dog.age) // ポチ 5
}

変数を定義時にフィールドにデータを渡す方法

type Dog struct {
	name string
	age  int
}

func main() {
  dog := Dog{"ポチ", 5}
  // フィールド名を渡しても可。
  // dog := Dog{name: "ポチ", age: 5}
  fmt.Println(dog.name, dog.age) // ポチ 5
}

補足

dog := Dog{name: "ポチ", age: 5}のようにフィールド名を指定したほうが、読みやすく、柔軟性もあるのでこちらを使ったほうが良いと思います。

構造体に構造体を定義

よくあるパターンとして、構造体に構造体を定義する方法について解説します。

構造体に構造体を定義

type Animal struct {
	name string
}

type Dog struct {
	age    int
	animal Animal
}

func main() {
	dog := Dog{age: 5, animal: Animal{name: "ポチ"}}
	fmt.Println(dog.animal.name, dog.age) // ポチ 5
}

フィールド名を省略するパターン

構造体の中に構造体を埋め込む場合、フィールド名が重複しなければ、フィールド名を省略することが可能です。

省略することによって、dog.animal.nameと書いていたところを、dog.nameのようにアクセスできます。

共通の性質を持たせる場合に非常に便利です。

type Animal struct {
	name string
}

type Dog struct {
	age int
	Animal
}

func main() {
	dog := Dog{age: 5, Animal: Animal{name: "ポチ"}}
	fmt.Println(dog.name, dog.age) // ポチ 5
}

メソッド

構造体にメソッドを定義することで、構造体にひもづく関数を定義することができます。

type Dog struct {
	name string
	age  int
}

func (dog Dog) bark() {
	fmt.Println("ワンワン")
}

func main() {
	dog := Dog{name: "ポチ", age: 5}
	dog.bark() // ワンワン
}

構造体とポインタ

構造体は値渡しになるので、ポインタを使って参照渡しをする必要があります。

モグモグさん

Goでは、ポインタ型で定義することが非常に多いので使い方を理解しましょう!

ポインタ型を使わない場合

// 座標を意味する構造体
type Coordinate struct {
	x, y int
}

// 座標xとyを入れ替えるメソッド
func swap(c Coordinate) {
	x, y := c.y, c.x
	c.x = x
	c.y = y
}

func main() {
	coordinate := Coordinate{x: 10, y: 100}
	swap(coordinate)
	fmt.Println(coordinate.x, coordinate.y) // 10 100 => 入れ替わっていない
}

ポインタ型を使う場合

// 座標を意味する構造体
type Coordinate struct {
	x, y int
}

// 座標xとyを入れ替えるメソッド
func swap(c *Coordinate) {
	x, y := c.y, c.x
	c.x = x
	c.y = y
}

func main() {
	coordinate := Coordinate{x: 10, y: 100}
	swap(&coordinate) // ポインタを渡す
	fmt.Println(coordinate.x, coordinate.y) // 100 10 => 入れ替わってる
}

Constructor

Goには、Constructorの機能がありませんが、一般的に使われる形式がありますので解説します。

コンストラクタを表す関数を定義

New [型名]のように命名するのが一般的です。

モグモグさん

多くのライブラリなどでも良く定義されているよ

type Dog struct {
	name string
	age  int
}

func NewDog(name string, age int) *Dog {
	dog := new(Dog)
	dog.name = name
	dog.age = age
	return dog
}

func main() {
	fmt.Println(NewDog("ポチ", 5)) // &{ポチ 5}
}

まとめ

Go言語の構造体(struct)の基本について解説しました。

Go言語を学習している方の参考になれば幸いです。