Goの構造体とinterface

構造体について

基本

GoにはDartKotlinに存在するクラスというものが存在しない。代わりに[Rust-MOC|Rust]のような構造体を提供している。
定義するにはtypestructキーワードを使用する。

type Animal struct {
	name string
	color string
	hasChild bool
	age int
}

この構造体を使用するには以下のようになる。

var cat Animal
cat.name = "mike"
cat.color = "gray"
cat.hasChild = false
cat.age = 2

{}を使用することもできる。

dog := Animal{"poti", "golden", "false", 4}

Mapのような記述方法も使用可能

monkey := Animal{
	name: "ukii",
	color: "brown",
	hasChild: true,
	age: 8
}

一般的にはファクトリ関数を作っておくのが良い。

func newAnimal(name string, color string, hasChild bool, age int) *Animal {
	animal := new(Animal)
	animal.name = name
	animal.color = color
	animal.hasChild = hasChild
	animal.age = age
}

構造体を使用したメソッドの定義

構造体はクラスではないので、通常ではその構造体に紐づいたメソッドは定義することができない。ただ、Goでは構造体に紐づいたメソッドを以下のような形式で紐づけ、メソッドを作成することができる。

type Animal struct {
	name string
	color string
	hasChild bool
	age int
}
 
func (a animal) greeting(voice string) string {
	return a.name + " bark " + voice
}

構造体の埋め込み

Goでは継承が存在しないが、構造体の埋め込みという機能を使用することで同様の動作を実装することができる。

type Animal struct {
	name string
	color string
	hasChild bool
	age int
}
 
type Cat struct {
	Animal
	kind string
}

Cat構造体内にAnimalを埋め込んだ状態になった。
このような書き方をすると、CatインスタンスはAnimalの持つフィールドにアクセス可能になる。

var a Animal
a.name = "mike"
a.color = "gray"
a.hasChild = false
a.age = 2
 
var cat = Cat{
	animal: a,
	kind: "mikeneko"
}
 

interface

GoではKotlinのようなinterfaceを使用可能である。ただクラスが存在しないのでその実態や実装は異なる。
typeinterfaceキーワードを使用してこのように定義する。

type AnimalInterface interface {
	Greeting() string
}

これを使用すると、

func voice(a AnimalInterface){
	fmt.Println(a.Greeting())
}

となる。

これを実際の使用法に直すと、

type Cat struct {
	a Animal,
	kind string
}
 
type Dog struct {
	a Animal,
	kind string
}
 
func (c Cat) Greeting() string {
	return c.name + " meow~"
}
 
func (d Dog) Greeting() string {
	return d.name + " bow!"
}
 
func voice(a AnimalInterface){
	fmt.Println(a.Greeting())
}
 
func main(){
	cat := //定義省略
	dog := //定義省略
	
	voice(cat) //$cat.name meow~
	voice(dog) //$dog.name bow!
}

注意点として、この例で言う、voice関数ではa.nameのように変数フィールドにはアクセスすることができない。あくまでinterfaceで定義されたメソッドだけである。