Golang:调用的接口方法在哪里?

Golang:调用的接口方法在哪里?,go,Go,我不明白在哪一点调用接口方法。我正在看以下Go Tour中的示例: 问题: 我知道func(p Person)接收String()方法,并返回我想要显示的字符串。但是main()方法中的fmt.Println必须在某个时候调用String(),对吗 我在godoc中查看了fmt的源代码,但我仍然无法找到它 另一个例子: 如果我添加自己的接口,让我们使用一个名为String2()的方法说Stringer2,然后创建一个func(p Person)String2(){..}。 String() 但是

我不明白在哪一点调用接口方法。我正在看以下Go Tour中的示例:

问题:

我知道
func(p Person)
接收
String()
方法,并返回我想要显示的
字符串。但是
main()
方法中的
fmt.Println
必须在某个时候调用
String()
,对吗

我在godoc中查看了
fmt
的源代码,但我仍然无法找到它

另一个例子:

如果我添加自己的接口,让我们使用一个名为
String2()
的方法说
Stringer2
,然后创建一个
func(p Person)String2(){..}

String()


但是,从
fmt
软件包打印时,其他方法可能优先。首先检查
fmt.Formatter
fmt.GoStringer
错误
,最后检查
fmt.Stringer

fmt
包与它定义的接口一起工作,在本例中是
Stringer
。它不知道您定义的接口,因此即使您将满足
Stringer2
接口的类型传递给它,它也不知道如何调用
String2()

接口是在类型之间具有共同行为的一种方式。因此,如果您创建一个函数
Foo(s Stringer2)
,Foo只需调用
s.String2()
,就可以确信传入它的任何东西都将具有函数
String2()

更深入一点,
fmt.Println
接受
interface{}
类型,然后使用反射检查给定参数是否符合
Stringer
接口,然后调用
String()


有意义吗?

在整个软件包中,它到处都会被调用(在print.go中有16个不同的位置)。我不会太担心的。试图解决如何打印一个特定的例子是相当困难和复杂的,该软件包处理所有类型的打印。。。它有很多不同的代码路径。我本打算尝试回答这个问题,但埃文是对的。不过,您是正确的,String在堆栈中的某个位置被调用,它可以工作,因为接口是基于方法名隐式满足的。
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)
}
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())
    }
}