我有以下功能:

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

//if (complicated thing) add Cat to m

}

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

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

Question:

mtreatsdogpassed-by-referencemeowId的值被复制了吗?

我假设:

  • m是通过引用传递的,因为它是一张 map
  • dog是一个 struct .因此,我应该传递指针以避免复制数据

推荐答案

接口类型只是一组方法.请注意,接口定义的成员不指定接收器类型是否为指针.那是因为the method set of a value type is a subset of the method set of its associated pointer type.那真是一张大嘴巴.我的意思是,如果您有以下条件:

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实现RenableCandy不实现.

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

Go相关问答推荐

如何禁用Go SRC包中的VSCode警告?

如何复制*C.char?

GORM没有从 struct 创建完整的表,如何修复?

错误.如果它包含切片,则返回FALSE

如何将GoFr筛选器用于查询参数?

格式化 Azure SDK 的 golang 时间

以编程方式取消 pyspark dataproc 批处理作业(job)

是否可以在 hyperledger-chaincode 中使用 gRPC?如果可以,我如何避免在测试网络上调用时出错?

下载和合并时输出文件已损坏

Opensearch 错误 ping 弹性服务器:由未知权威签署的 x509 证书

如何将整数哈希细分为范围

SSH 代理,数据包长度错误

如何将具有嵌入式 struct 的 struct 展平为 json

如何使用 math/big 对 bigInt 进行取模?

有没有办法判断值是否满足接口中定义的类型约束?

GoLang 遍历 yaml 文件

httprouterhttp.HandlerFunc() 是如何工作的?

从 Go struct 中提取标签作为 reflect.Value

如何在 docker 文件中安装 golang 包?

golangci-lint 的 GitHub 操作失败,无法加载 fmt