インターフェースへのポインタ

ほとんどの場合、インターフェース型へのポインタはほとんど必要ありません。インターフェースは値として渡すべきであり、その際に渡されるデータは依然としてポインタである場合があります。

基本的に、インターフェースは以下の2つのフィールドで表されます:

  1. 特定の型情報へのポインタ。これを「型」と考えることができます。
  2. データへのポインタ。格納されるデータがポインタであれば、それが直接格納されます。値である場合は、その値へのポインタが格納されます。

インターフェースメソッドで基礎となるデータを変更したい場合は、ポインタレシーバを使用する必要があります(オブジェクトのポインタをインターフェース変数に割り当てます)。

type F interface {
  f()
}

type S1 struct{}

func (s S1) f() {}

type S2 struct{}

func (s *S2) f() {}

// f1.f() は基礎となるデータを変更できません
// f2.f() は基礎となるデータを変更できます。オブジェクトのポインタがインターフェース変数 f2 に割り当てられます
var f1 F = S1{}
var f2 F = &S2{}

インターフェースへのポインタを使用しないでください。Go言語では、インターフェース自体が参照型です。言い換えれば、インターフェース型そのものがポインタです。必要なのは、テスト用のパラメーターだけが myinterface であることであり、値を渡す際は *mystruct 型を渡す必要があります(そして値を渡す場合も *mystruct 型しか渡すことができません)。

type myinterface interface {
  print()
}

func test(value *myinterface) {
  //何かを行う...
}

type mystruct struct {
  i int
}

// インターフェースを実装
func (this *mystruct) print() {
  fmt.Println(this.i)
  this.i = 1
}

func main() {
  m := &mystruct{0}
  test(m) // 間違い
  test(*m) // 間違い
}