harukin721

主に学習記録

Go の Interface と Struct

Interface(実装を持たない抽象型であり、メソッドのシグネチャを定義することで、他の型がそのインターフェースを実装できる) と Struct(type指定されたフィールドの集合であり、データの構造を表現する)

k8sでよく使われる

Reconcilerのinterfaceで、ReconcileメソッドがContextとRequestを引数に取り、Resultとerrorを返す。

type Reconciler interface {
    Reconcile(context.Context, Request) (Result, error)
}

Structの簡単な例

Personというstructを宣言

type Person struct {
Id int
  Name string
}

structにメソッドを追加 ( `func レシーバ メソッド名(引数リスト) 戻り値リスト {}` )

# レシーバ(変数:p 型:Person)
func (p Person) GetName() string {
  return p.Name
}

# nameを引数として取って、p.Nameを更新する
# 「*」が付いているのはポインタレシーバ(フィールドを変更する)
# 大きなデータ構造だとコピーを作るのはメモリを消費するのでポインタを利用し、直接操作するのが効率的
func (p *Person) SetNmae(name string) {
  p.Name = name
}

structを使っていく

# インスタンスを初期化
# := を使う時はstructのリテラル{}を使う
func main() {
  p := Person{Id: 721, Name: "harukin"}
  fmt.Println(p) // {721 harukin}
  p.SetName("uejima")
   fmt.Println(p.GetName) // uejima
}

Embedding(継承みたいなものと理解している)

# Personが持っているメソッドやフィールドをそのまま使える
type Hoge struct {
 Person
OtherField string
}

main関数を変更

func main() {
  p := Person{Id: 721, Name: "harukin"}
h := Hoge{Person: p}
  fmt.Printf("id: %d, name: %s\n", h.Id, h.Name) // {id: 721, name: harukin}

   h = Hoge{Person{Id: 721, Name:"uejima"},"Other"}
  p.SetName("Uejima")
   fmt.Println(h.GetName) // uejima
}

Interfaceの簡単な例

Objectというinterfaceを宣言

type Object interface {
   GetName() string
}

PersonもHogeもGetNameという関数を持ち、オブジェクトのInterfaceを実装している

func main() {
  p := Person{Id: 721, Name: "harukin"}
   printObjectName(&p) // harukin
h := Hoge{Person: p}
   printObjectName(&h) // harukin

   h = Hoge{Person{Id: 721, Name:"uejima"},"Other"}
  printObjectName(&h) // uejima
}

// Objectインターフェースを受け取る
// GetNameメソッドを呼び出してオブジェクトの名前を出力
func printObjectName (obj Object) {
fmt.Println(obj. GetName())
}

最初よりは理解ができている。はず。