インターフェイスタイプは、単に一連のメソッドです。インターフェイス定義のメンバーは、レシーバータイプがポインターであるかどうかを指定しないことに注意してください。これは、値型のメソッドセットが、関連するポインタ型のメソッドセットのサブセットであるためです。それは一口です。私が言いたいのは、あなたが以下を持っている場合です:
type Whatever struct {
Name string
}
そして、次の2つのメソッドを定義します。
func (w *Whatever) Foo() {
...
}
func (w Whatever) Bar() {
...
}
その場合、タイプWhatever
にはメソッドのみが含まれBar()
、タイプ*Whatever
にはメソッドFoo()
とが含まれBar()
ます。つまり、次のインターフェイスがある場合です。
type Grits interface {
Foo()
Bar()
}
次に、*Whatever
実装しますが、メソッドGrits
がWhatever
ないため、実装しません。関数への入力をインターフェイス型として定義する場合、それがポインタ型であるか値型であるかはわかりません。Whatever
Foo()
次の例は、両方の方法でインターフェイスタイプを受け取る関数を示しています。
package main
import "fmt"
type Fruit struct {
Name string
}
func (f Fruit) Rename(name string) {
f.Name = name
}
type Candy struct {
Name string
}
func (c *Candy) Rename(name string) {
c.Name = name
}
type Renamable interface {
Rename(string)
}
func Rename(v Renamable, name string) {
v.Rename(name)
// at this point, we don't know if v is a pointer type or not.
}
func main() {
c := Candy{Name: "Snickers"}
f := Fruit{Name: "Apple"}
fmt.Println(f)
fmt.Println(c)
Rename(f, "Zemo Fruit")
Rename(&c, "Zemo Bar")
fmt.Println(f)
fmt.Println(c)
}
を呼び出すことはできますRaname(&f, "Jorelli Fruit")
がRename(c, "Jorelli Bar")
、Fruit
を*Fruit
実装Renamable
する*Candy
ことはできません。Renable
Candy
http://play.golang.org/p/Fb-L8Bvuwj