golang pointers on pointers as function parameters

go, pointers

Solution

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

Problem

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

Original source