指针上的golang指针作为函数参数 [英] golang pointers on pointers as function parameters

查看:308
本文介绍了指针上的golang指针作为函数参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有函数

pre $ func addCatsToMap(m map [string] [] CatHouse,meowId int,对待Set,dog * Dog){

// if if(complex thing)add Cat to m

}

这是真的,m,treats和dog是通过引用传递的,meowId是它的值被复制的。

由于m是map,所以它是通过引用传递的。

Dog是一个结构体。因此,我应该通过指针来避免复制数据。

Set是一个接口,如下定义:

 类型Set接口{
Add(value string)
包含(值字符串)(bool)
Length()(int)
RemoveDuplicates()
}

设置传递值吗?

解决方案

接口类型只是一组方法。请注意,接口定义的成员不指定接收器类型是否是指针。这是因为值类型的方法集是其关联指针类型的方法集的一个子集。这是一口。我的意思是,如果你有以下内容:

 类型无论结构{
名称字符串
}

并且定义了以下两种方法:

< pre $ func(w * Whatever)Foo(){
...
}

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

然后输入无论什么只有方法 Bar(),而类型 * Whatever 具有方法 Foo() Bar()。这意味着如果你有以下接口:

  type Grits interface {
Foo()
Bar )
}

然后 *随便 implements Grits 不管什么都没有,因为无论缺少方法 Foo()。当您将函数的输入定义为接口类型时,您不知道它是一个指针还是一个值类型。



以下示例演示了一个函数,两种方式的接口类型:

 包主
$ b导入fmt

类型水果结构{
名称字符串
}

func(f水果)重命名(名称字符串){
f.Name =名称
}

类型Candy结构{
名称字符串
}

func(c * Candy)重命名(名称字符串){
c.Name = name


类型Renamable接口{
重命名(字符串)
}

func重命名(v Renamable,name string){
v.Rename(name)
//此时,我们不知道v是否是指针类型。


func main(){
c:= Candy {Name:Snickers}
f:= Fruit {Name:Apple}
fmt.Println(f)
fmt.Println(c)
重命名(f,Zemo Fruit)
重命名(& c,Zemo Bar)
fmt。 Println(f)
fmt.Println(c)
}

你可以调用 Raname(& f,Jorelli Fruit)但不是 Rename(c,Jorelli Bar),因为 Fruit * Fruit 实现可重命名,而 * Candy 实现 Renable Candy 不会。



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


I have the function

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

//if (complicated thing) add Cat to m

}

Is it true that m, treats, and dog are passed-by-reference, and meowId has it's value copied.

Since m is map, its pass-by-reference.

Dog is a struct. So, I should pass the pointer to avoid copying the data.

Set is an interface, as defined here:

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

Is Set pass-by-value?

解决方案

An interface type is simply a set of methods. Notice that the members of an interface definition do not specify whether or not the receiver type is a pointer. That is because the method set of a value type is a subset of the method set of its associated pointer type. That's a mouthful. What I mean is, if you have the following:

type Whatever struct {
    Name string
}

and you define the following two methods:

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

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

Then the type Whatever has only the method Bar(), while the type *Whatever has the methods Foo() and Bar(). That means if you have the following interface:

type Grits interface {
    Foo()
    Bar()
}

Then *Whatever implements Grits but Whatever does not, because Whatever lacks the method Foo(). When you define the input to a function as an interface type, you have no idea whether it's a pointer or a value type.

The following example illustrates a function that takes an interface type in both ways:

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)
}

you could call Raname(&f, "Jorelli Fruit") but not Rename(c, "Jorelli Bar"), because both Fruit and *Fruit implement Renamable, while *Candy implements Renable and Candy does not.

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

这篇关于指针上的golang指针作为函数参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆