接口類型只是一組方法。請注意,接口定義的成員不指定接收器類型是否是指針。這是因爲值類型的方法集是其關聯的指針類型的方法集的子集。這是一口。我的意思是,如果你具備以下條件:
type Whatever struct {
Name string
}
,並定義了以下兩種方法:
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