猿问

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

我不明白在哪一点调用接口方法。我正在查看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)

}

问题:


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


我查看了fmtin godoc的来源,但我仍然无法弄清楚!


另一个例子:


如果我添加我自己的接口,让我们说Stringer2一个调用的方法String2(),然后创建一个func (p Person) String2() {....}. 如何String()被执行fmt.Println,但String2()不执行?


暮色呼如
浏览 187回答 2
2回答

梵蒂冈之花

该值传递给Println作为interface{},并检查它是否满足fmt.Stringer通过一个接口“类型断言”通常以的形式“型开关”。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())    }}但是,从fmt包装中打印时,其他方法可能优先。首先检查fmt.Formatter, fmt.GoStringer, error, 最后检查fmt.Stringer。

GCT1015

该fmt包与它定义的接口工作,在这种情况下Stringer。它不知道您定义的接口,因此String2()即使您将满足该Stringer2接口的类型传递给它,它也不知道调用。接口是一种在类型之间具有共同行为的方式。因此,如果您创建一个函数Foo(s Stringer2),Foo 可以简单地调用s.String2()确信传入它的任何内容都将具有该函数String2()。更深入一点,fmt.Println获取interface{}类型,然后使用反射来检查给定的参数是否满足Stringer接口,然后调用String().有道理?
随时随地看视频慕课网APP

相关分类

Go
我要回答