[英]Golang: Where is an Interface method called?
I don't understand at which point an Interface method is being called. 我不明白在哪一点上调用了Interface方法。 I'm looking at the following example from the Go Tour :
我正在看Go Go中的以下示例:
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. 我知道
func (p Person)
接收String()
方法并返回我想要显示的string
。 But the fmt.Println
in the main()
method has to call String()
at some point, right? 但是
main()
方法中的fmt.Println
必须在某个时刻调用String()
,对吗?
I had a look at the source of fmt
in godoc , but I still cannot figure it out! 我看过godoc的
fmt
来源 ,但我仍然无法弄明白!
Another example: 另一个例子:
If I add my own interface, lets say Stringer2
with a method called String2()
and then create a func (p Person) String2() {....}
. 如果我添加自己的接口,让我们说
Stringer2
使用一个名为String2()
的方法,然后创建一个func (p Person) String2() {....}
。 How does String()
get executed by fmt.Println
, but String2()
not? String()
如何被fmt.Println
执行,但fmt.Println
String2()
不是?
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" . 该值被传递到
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())
}
}
However, other methods may take precedence when printing from the fmt
package. 但是,从
fmt
软件包打印时,其他方法可能优先。 There are first checks for fmt.Formatter
, fmt.GoStringer
, error
, and then finally fmt.Stringer
. 首先检查
fmt.Formatter
, fmt.GoStringer
, error
,然后最后fmt.Stringer
。
The fmt
package works with the interfaces it defines, in this case Stringer
. fmt
包与它定义的接口一起使用,在本例中为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. 它不知道你定义的接口,所以即使你传递一个符合
Stringer2
接口的类型,它也不会知道调用String2()
。
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()
. 所以如果你创建一个函数
Foo(s Stringer2)
,Foo可以简单地调用s.String2()
确信传入它的任何东西都有函数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()
. 为了更深入,
fmt.Println
采用interface{}
类型,然后使用反射来检查给定的参数是否符合Stringer
接口,然后调用String()
。
Make sense? 合理?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.