面试题答案
一键面试在Go语言中,方法集定义了一个类型可以调用的方法集合。对于接口调用,方法集决定了接口方法的查找与调用规则:
- 指针接收器方法集:如果一个结构体类型的方法使用指针接收器声明,那么只有指向该结构体的指针类型才拥有这个方法集。例如:
type User struct {
Name string
}
func (u *User) SayHello() {
println("Hello, ", u.Name)
}
这里User
结构体的SayHello
方法使用指针接收器。只有*User
类型有SayHello
方法,User
类型没有。如果接口类型被赋值为*User
类型的实例,那么在调用接口方法时,会查找*User
的方法集。
- 值接收器方法集:如果一个结构体类型的方法使用值接收器声明,那么该结构体的指针类型和值类型都拥有这个方法集。例如:
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return 3.14 * c.Radius * c.Radius
}
这里Circle
结构体的Area
方法使用值接收器。Circle
类型和*Circle
类型都有Area
方法。当接口类型被赋值为Circle
或*Circle
类型的实例时,在调用接口方法时,会查找对应的方法集。
结构体方法集与接口调用关系举例:
package main
import (
"fmt"
)
type Animal interface {
Speak() string
}
type Dog struct {
Name string
}
func (d Dog) Speak() string {
return "Woof!"
}
type Cat struct {
Name string
}
func (c *Cat) Speak() string {
return "Meow!"
}
func main() {
var a Animal
dog := Dog{Name: "Buddy"}
a = dog
fmt.Println(a.Speak())
cat := &Cat{Name: "Whiskers"}
a = cat
fmt.Println(a.Speak())
}
在这个例子中,Dog
的Speak
方法使用值接收器,Cat
的Speak
方法使用指针接收器。在main
函数中,我们分别将Dog
实例和*Cat
实例赋值给Animal
接口,然后调用Speak
方法,这体现了结构体方法集对接口方法查找与调用的影响。