一尘不染

指针上的golang指针作为函数参数

go

我有以下功能:

func addCatsToMap(m map[string][]CatHouse, meowId int, treats Set, dog *Dog) {

//if (complicated thing) add Cat to m

}

其中Set,的类型treats是具有以下定义的接口:

type Set interface {
  Add(value string)
  Contains(value string) (bool)
  Length() (int)
  RemoveDuplicates()
}

题:

这是真的mtreatsdog通过按引用 ,并且meowId有它的价值被复制?

我认为:

  • m 是通过引用的,因为它是一张地图
  • dog是一个结构。因此,我应该传递指针以避免复制数据

阅读 195

收藏
2020-07-02

共1个答案

一尘不染

接口类型只是一组方法。请注意,接口定义的成员未指定接收方类型是否为指针。这是因为 值类型的方法集是其关联的指针类型的方法集的子集 。满嘴
我的意思是,如果您具有以下条件:

type Whatever struct {
    Name string
}

然后定义以下两种方法:

func (w *Whatever) Foo() {
    ...
}

func (w Whatever) Bar() {
    ...
}

然后类型Whatever只有方法Bar(),而类型*Whatever只有方法Foo()Bar()。这意味着如果您具有以下界面:

type Grits interface {
    Foo()
    Bar()
}

然后*Whatever执行GritsWhatever不执行,因为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工具RenableCandy没有。

http://play.golang.org/p/Fb-L8Bvuwj

2020-07-02