我有这个功能
func addCatsToMap(m map[string][]CatHouse,meowId int,treats Set,dog *Dog) { //if (complicated thing) add Cat to m }
这是真的,m,对待和狗被引用参考,并且meowId有价值复制。
由于m是地图,其通过引用。
狗是一个结构体。所以,我应该传递指针以避免复制数据。
Set是一个接口,如下所定义:
type Set interface { Add(value string) Contains(value string) (bool) Length() (int) RemoveDuplicates() }
设置pass-by-value?
接口类型只是一组方法。请注意,接口定义的成员不指定接收器类型是否是指针。这是因为值类型的方法集是其关联指针类型的方法集的子集。那是一口气我的意思是,如果你有以下几点:
type Whatever struct { Name string }
您定义了以下两种方法:
func (w *Whatever) Foo() { ... } func (w Whatever) Bar() { ... }
然后类型不管有什么方法Bar(),而类型*无论有什么方法Foo()和Bar()。这意味着如果您有以下界面:
type Grits interface { Foo() Bar() }
然后*无论什么实现Grits,但无论什么不,因为无论什么缺乏方法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”),但不能重命名(c,“Jorelli Bar”),因为Fruit和* Fruit都可以实现Renamable,而* Candy实现了Renable和Candy。