Golang:接口方法在哪里?

I don't understand at which point an Interface method is being called. I'm looking at the following example from the Go Tour:

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

Problem:

I understand that the func (p Person) receives the String() method and that it returns the string I want to display. But the fmt.Println in the main() method has to call String() at some point, right?

I had a look at the source of fmt in godoc, but I still cannot figure it out!

Another example:

If I add my own interface, lets say Stringer2 with a method called String2() and then create a func (p Person) String2() {....}. How does String() get executed by fmt.Println, but String2() not?

The value is passed to Println as an interface{}, and is checked if it satisfies the fmt.Stringer interface via a "type assertion" often in the form of a "type switch".

func IsStringer(i interface{}) {
    switch s := i.(type) {
    case fmt.Stringer:
        fmt.Println("Person a has a String() method")
        fmt.Println(s.String())
    default:
        fmt.Println("not a stringer")
    }

    // OR for a single type

    if s, ok := i.(fmt.Stringer); ok {
        fmt.Println("Person a has a String() method")
        fmt.Println(s.String())
    }
}

However, other methods may take precedence when printing from the fmt package. There are first checks for fmt.Formatter, fmt.GoStringer, error, and then finally fmt.Stringer.

The fmt package works with the interfaces it defines, in this case Stringer. It does not know of interfaces defined by you so it wouldn't know to call String2() even if you pass it a type that meets the Stringer2 interface.

Interfaces are a way to have common behavior between types. So if you create a function Foo(s Stringer2), Foo can simply call s.String2() confident that anything passed into it will have the function String2().

To go a bit deeper, fmt.Println takes interface{} types and then uses reflection to check if the given argument meets the Stringer interface to then call String().

Make sense?