【第九回Go言語学習備忘録】Struct(構造体)を理解する!

どもです。コムデギャルソンの服、興味はあるけど着る勇気はないsaisaiです。


今回はGo言語学習備忘録シリーズということで、Struct(構造体)について学んだことを記事にまとめていきたいと思います。


こちらも様々なコードで必ずといっていいほどよく見かけるものですので、気合をいれて取り掛かりたいと思います。

Structを使って理解してみる

まずはStructを使って実際にコードを書いてみたいと思います。

package main

import "fmt"

type Sample struct {
	x int
	y string
}

func main() {
	v := Sample{x: 3, y: "ピース"}
	fmt.Println(v)
	fmt.Println(v.x, v.y)
	}

出力結果は以下の通りになります。

saisai % go run main.go
{3 ピース}
3 ピース

まず注目すべきはStructの構造です。ここを理解することがStructを使いこなす上での第一歩となります。

type Sample struct {
	x int
	y string
}

こちらはSampleという構造体を作成し、その中に2つの変数を定義しています。ここは必ずしも2つである必要はありません。今回の場合、"x"というint型の変数と"y"というstring型の関数をSampleという名前の構造体で一挙に定義しています。作成した構造体は以下のように使用できます。

func main() {
	v := Sample{x: 3, y: "ピース"} //構造体のそれぞれの変数に値を代入している
	fmt.Println(v)
	fmt.Println(v.x, v.y)
	}

値の代入方法は上記コードの通りです。注意すべきはその呼び出し方です。上記のコードの場合、変数に値を代入したStructを変数"v"に代入しています。したがって、変数"v"をそのまま出力するとStructそのものが呼びだされてしまいます。

fmt.Println(v)
// {3 ピース}

Structで定義した値を取り出す場合は以下のように、Structを代入した変数(v)とStructの中の変数(x,y)をそれぞれ指定して出力する必要があります。

fmt.Println(v.x, v.y)
// 3 ピース


EmbeddedでStructを継承っぽく利用できる

一度定義したStructを引き継ぐ形で使用する"継承"のようなこともできます(他の言語でいう"継承"とは少々異なるようですが)。例えば以下のように定義します。

package main

import "fmt"

type Sample struct {
	x int
	y string
}

type Sample2 struct {
	Sample //上記で定義したStructを引用できる
	z string
}

func main() {
	v := Sample{x: 3, y: "ピース"}
	v2 := Sample2{Sample: Sample{x: 3, y: "ピース"}, z: "バンド"}
	fmt.Println(v.x, v.y) 
	fmt.Println(v2.x, v2.y, v2.z)
}

出力結果はこんな感じです。

saisai % go run main.go
3 ピース
3 ピース バンド

まずは元々作成していたStruct(Sample)を継承して、新たに"Sample2″というStructを作成します。

type Sample2 struct {
	Sample
	z string
}

Struct"Sample2″はもともとSampleがもつ変数"int型のx"と"string型のy"に加えて、"string型のz"を定義された状態となります。

次に出力方法ですが、EmbeddedされたStructの値を取り出すには少々特殊な指定方法が必要です。

	v2 := Sample2{Sample: Sample{x: 3, y: "ピース"}, z: "バンド"}
	fmt.Println(v2.x, v2.y, v2.z} // 3 ピース バンド

出力方法自体は、基本的にStructと相違ありません。指定する変数がEmbeddedした分追加されるといった感じでしょう。問題は変数への代入方法です。構造としては以下のようになっていそうです。

変数 := EmbeddedされたStruct{元のStruct:元のstruct{その値},新たに追加された変数:値}

まず、"元のStruct"と"新しく追加された変数"に大きく分けそれぞれに値を入力していくという考え方が個人的にはしっくりきています。

ひとこと

今回はStructについて学んだことをまとめてみました。言語化するのは本当にむずかしいですね…。しかし、Structはコードの序盤に定義しておくことで様々な場面で活用できるので大変便利だと思います!


次回はStructを使用したメソッドの定義方法について学習する予定です。まだまだStructとは向き合っていかなければなりませんね、頑張ります!


ここまで読んでいただきありがとうございました!


-saisai-

Golang

Posted by CY