接口类型只是一组方法。请注意,接口定义的成员不指定接收器类型是否为指针。这是因为值类型的方法集是其关联指针类型的方法集的子集。那是一口。我的意思是,如果您有以下情况:
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