douxing9567 2012-06-21 01:59
浏览 98
已采纳

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

I have the following function:

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

//if (complicated thing) add Cat to m

}

where Set, the type of treats, is an interface with the following definition:

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

Question:

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

I assume that:

  • m is pass-by-reference because it's a map
  • dog is a struct. So, I should pass the pointer to avoid copying the data
  • 写回答

3条回答 默认 最新

  • dongzhuxun5136 2012-06-21 04:06
    关注

    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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)