Goの構造体とinterface
構造体について
基本
GoにはDartやKotlinに存在するクラスというものが存在しない。代わりに[Rust-MOC|Rust]のような構造体を提供している。
定義するにはtypeとstructキーワードを使用する。
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を使用可能である。ただクラスが存在しないのでその実態や実装は異なる。
typeとinterfaceキーワードを使用してこのように定義する。
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で定義されたメソッドだけである。