Go 当指针类型作为接收者时,只有*person类型实现了该接口 perrson 没有

18 min read

实际上,即使指针类型作为接收者时,仍然可以将非指针类型实现的接口赋值给该接口变量。例如,以下代码可以正常编译:

type Person interface {
    SayHello()
}

type person struct {
    name string
}

func (p *person) SayHello() {
    fmt.Println("Hello, my name is", p.name)
}

func main() {
    var p Person
    p = &person{"Alice"}
    p.SayHello() // 输出:Hello, my name is Alice

    q := person{"Bob"}
    // 下面这行代码编译时不会报错,但运行时会 panic:
    // runtime error: invalid memory address or nil pointer dereference
    p = q
    p.SayHello()
}

在上面的代码中,person*person 都实现了 Person 接口,因此可以将它们赋值给 p。注意到在第二个赋值语句中,虽然 q 是非指针类型,但仍然可以将其赋值给 p。然而,在调用 p.SayHello() 时,对 q 的调用会导致运行时错误,因为此时 p 是一个空指针。因此,需要在将 q 赋值给 p 之前,将其转换为 *person 类型。