5
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Go の Embedded を理解する

Go で継承みたいなことをしたい時は Embedded のしくみを使える。ふわっとしかわかってないことに気づいたけど、リファレンスレベルだけど、自分用に整理しておく

Embedded が使える種類

interface と struct に対して使える。

interface

type Reader interface {
  Read(p []byte) (n int, err error) 
}
type Writer interface {
  Write(p []byte)(n int, err error)

type ReadWriter interface {
  Reader
  Writer
}

struct

struct の場合は、ポインタで書くこと

embeded should be pointer

type ReadWriter struct {
   *bufio.Reader
   *bufio.Writer
}

struct の初期化

struct の Embedded を使ったら初期化しないといけない。

type Job struct {
  Common string
  *log.Logger
}

というEmbeddedを持っているとき初期化の際には初期化してEmbedded を持たせてあげる必要がある。

func NewJob(command string, logger *log.Logger) *Job {
  return &Job{command, logger}
}
or
job := &Job{command, log.New(os.Stderr, "Job: ", log.Ldate)}

struct のオーバーライド

Embedded を次のようにも書ける。その際には、自分でデリゲートしてあげる必要がある。おそらくメソッドをオーバーライドしたい時に使える。

func (job *Job) Logf(format string, args ...interface{}) {
   job.Logger.Logf("%q: %s", job.Command, fmt.Sprintf(format, args...))
}

また、自分で次のように書いてオーバーライドしても良い

type ReadWriter struct {
    reader *bufio.Reader
}

func (rw *ReadWriter) Read(p []byte) (n int, err error) {
   return rw.reader.Read(p)
}

関数が重複したら?

Embedded を使った Struct と元の struct の関数のシグネチャが重複したら、Embedded を使った方が優先させる。(Job と Logger では、Job の関数が優先)また、Embedded した元の struct で誰かが重複させてしまった場合、その場合でも、Job の方はプロテクションの機構が働いて、使えはする。その重複しているメンバにアクセスしない限りは。

まとめ

リファレンスのまんまですが、自分の整理のために書きました。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
5
Help us understand the problem. What are the problem?