Confusing about implement Stringer interface

Hi,
I am a newcomer for Go and I`m studying the offical tour of Go. I have some question on this tour
A Tour of Go complete code are at the bottom.
when I change the receiver of

func (p Person) String() string

to

func (p *Person) String() string

it doesnt print the string returned by String method.
it seems like the String method didnt be called within the fmt.Println() call.
Any help would be appreciated. thanks very much! :slight_smile:

package main

import "fmt"

type Person struct {
	Name string
	Age  int
}

func (p Person) String() string {
	return fmt.Sprintf("%v (%v years)", p.Name, p.Age)
}

func main() {
	a := Person{"Arthur Dent", 42}
	z := Person{"Zaphod Beeblebrox", 9001}
	fmt.Println(a, z)
}

Hi! When you pass a and z to fmt.Println Go converts them into interface{} in the first step (keep in mind this). Then with a type switch it sees that you’ve passed a value that ISN’T a fmt.Stringer because you’ve defined String() on *Person and not Person, which is different.
fmt.Println should do something like this:

switch v := v.(type) {
case string:
    os.Stdout.WriteString(v)
case fmt.Stringer:
    os.Stdout.WriteString(v.String())
// ...
}

To proof this, change your line fmt.Println(a, z) to fmt.Println(&a, &z) and it works :slight_smile: .

2 Likes

thank you very much! I got it.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.