官方对函数的调用规则说明为: A method call x.m() is valid if the method set of (the type of) x contains m and the argument list can be assigned to the parameter list of m. If x is addressable and &x’s method set contains m, x.m() is shorthand for (&x).m().
dataCopy:=*iface.data// dereference iface.datadereferenced:=*dataCopy// dereference the pointer at iface.datatypedData:=dereferenced.(Person)// assertPerson_SPEAK(typedData)
interface 存储值且方法为值调用
interface 首先解引用 data,然后断言其为具体类型,接着进行调用。
1
2
3
4
5
6
dataCopy:=*iface.data// dereference (extract the value)typedData:=dataCopy.(Person)// assertPerson_SPEAK(typedData)
进一步讨论
以下内容来自Go interfaces, the tricky parts,写的非常好。
为什么以下代码无法编译:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
packagemainfuncmain(){users:=[]User{User{"alice"},User{"bob"}}// hint: this line compiles, User fulfils Namedvar_Named=User{"charlie"}getName(users[0])getNames(users)}typeNamedinterface{name()string}typeUserstruct{fullNamestring}func(uUser)name()string{returnu.fullName}funcgetName(nNamed)string{returnn.name()}funcgetNames(ns[]Named)[]string{returnnil}
在编译 getNames(users) 时,编译器会提示:
cannot use users (variable of type []User) as []Named value in argument to getNames
为什么?User 实现了 name 方法,并且var _ Named = User{"charlie"}也表明 golang 确认了这一点。