go 语言 在动态值为 nil 的接口上调用方法

在动态值为 nil 的接口上调用方法

把一个值为nil的某个实现类型的变量赋给了接口变量,是否可以在这个接口变量上调用该接口的方法

lib/lib.go

type People struct {
	Name string
	Age  int
}

type Superman struct {
	People
	color string
}

type Mutant interface {
	Speaking()
}

type Fly interface {
	Fly()
}

func (sp Superman) Speaking() {
	fmt.Printf("I'm %s", sp.Name)
}

func (sp *Superman) Fly() {
	fmt.Println("I can fly")
}

value.go

func callMethodOnNil() {
	var mu lib.Mutant
	var xman *lib.Superman

	fmt.Println("xman:", xman) // nil
	mu = xman
	fmt.Println("mu:", mu) // nil
	// Panic: runtime error: invalid memory address or nil pointer dereference
	// 动态类值为 nil 时,不能在其上调用值方法
	// mu.Speaking()

	var fly lib.Fly
	fmt.Println("xman:", xman) // nil
	fly = xman
	fmt.Println("fly:", fly) // nil

	// 动态类值为 nil 时,可以在其上调用指针方法
	// Fly()方法可以被调用,它的接收者是 *T 类型,且方法中没有涉及到对类型属性的调用
	fly.Fly() // I can fly
}

小结

  1. 值类型(T)的方法不能被调用,无论这个方法中是否涉及了对类型属性的调用

  2. 指针类型(*T)的方法可以被调用,但方法中不能涉及类型属性的调用