MST

星途 面试题库

面试题:Go接口调用过程中方法集的作用

请简述在Go语言接口调用过程中,方法集是如何影响接口方法的查找与调用的,并举例说明结构体方法集与接口调用之间的关系。
15.5万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

在Go语言中,方法集定义了一个类型可以调用的方法集合。对于接口调用,方法集决定了接口方法的查找与调用规则:

  1. 指针接收器方法集:如果一个结构体类型的方法使用指针接收器声明,那么只有指向该结构体的指针类型才拥有这个方法集。例如:
type User struct {
    Name string
}

func (u *User) SayHello() {
    println("Hello, ", u.Name)
}

这里User结构体的SayHello方法使用指针接收器。只有*User类型有SayHello方法,User类型没有。如果接口类型被赋值为*User类型的实例,那么在调用接口方法时,会查找*User的方法集。

  1. 值接收器方法集:如果一个结构体类型的方法使用值接收器声明,那么该结构体的指针类型和值类型都拥有这个方法集。例如:
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())
}

在这个例子中,DogSpeak方法使用值接收器,CatSpeak方法使用指针接收器。在main函数中,我们分别将Dog实例和*Cat实例赋值给Animal接口,然后调用Speak方法,这体现了结构体方法集对接口方法查找与调用的影响。