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