斯金格斯的困惑行为?

New to Go, so please bear with me.

I've been looking at the "Tour of Go" pages, and stumbled into something puzzling about Stringers. Consider the exercise at https://tour.golang.org/methods/18

My initial answer was implementing

func (this *IPAddr) String() string {
  return fmt.Sprintf("%d.%d.%d.%d", this[0], this[1], this[2], this[3])
}

however, this is not used f main prints just fmt.Printf("%v: %v ", name, ip). If I change the print to fmt.Printf("%v: %v ", name, ip.String()), then it is used whether the receiver type is *IPAddr or IPAddr).

why is this happening?

Because you're passing an IPAddr value to fmt.Printf, your String() method isn't part of the method set. Your solution works if you pass in a pointer:

fmt.Printf("%v: %v
", name, &ip)

But a general solution is to not use a pointer receiver:

func (ip IPAddr) String() string {
  return fmt.Sprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3])
}

This way the String() method can be used from an IPAddr, which is what you're passing to Printf, or an *IPAddr, which includes the methods of the value receiver.

Firstly, never call method receiver this. It's against the Style.

Secondly, you've defined method on *IPAddr, not IPAddr. Do this:

func (ip IPAddr) String() string {
    return fmt.Sprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3])
}