如何理解
如果一个函数的参数是接口类型,传进去的参数可以是指针,也可以不是指针,这得看你传的对象是怎么实现这个接口类型的 如果实现接口的方法的接收器是指针类型,则传参给接口类型时必需是指针,如果不是,则随便传?
这段话的意思是,
- 如果一个函数的参数是接口类型,那么这个参数可以接收任何实现了该接口的类型的值。
- 这个值既可以是指针类型,也可以是非指针类型,取决于实现接口的类型的方法的接收器类型。
- 如果实现接口的方法的接收器是指针类型,那么在传参给接口类型时,必须将该类型的值作为指针传入。
- 否则,将该类型的值作为非指针传入,编译器将会报错。
例如,假设我们有一个接口类型 MyInterface
,和一个实现了该接口类型的结构体类型 MyStruct
,其中 MyStruct
类型的方法的接收器类型为指针类型:
type MyInterface interface {
MyMethod()
}
type MyStruct struct{}
func (p *MyStruct) MyMethod() {}
现在,如果我们定义一个函数,其参数为 MyInterface
类型:
func MyFunction(p MyInterface) {}
那么,我们可以将一个指向 MyStruct
类型的指针作为参数传递给该函数,例如:
var p *MyStruct = &MyStruct{}
MyFunction(p)
这是因为,实现接口的方法的接收器类型是指针类型,因此在传参给接口类型时,必须将该类型的值作为指针传入。如果我们将 MyStruct
类型的值作为非指针传入,编译器将会报错:
var p MyStruct = MyStruct{}
MyFunction(p) // compilation error: cannot use p (type MyStruct) as type MyInterface in argument to MyFunction
因此,我们必须将 MyStruct
类型的值作为指针传入:
var p *MyStruct = &MyStruct{}
MyFunction(p)
而对于实现接口的方法的接收器类型为非指针类型的情况,我们既可以将该类型的值作为指针传入,也可以将该类型的值作为非指针传入。例如,假设我们有一个实现了 MyInterface
接口的结构体类型 MyStruct2
,其中 MyStruct2
类型的方法的接收器类型为非指针类型:
type MyStruct2 struct{}
func (p MyStruct2) MyMethod() {}
现在,我们可以将 MyStruct2
类型的值作为指针或非指针传递给参数类型为 MyInterface
的函数,例如:
var p MyStruct2 = MyStruct2{}
MyFunction(p)
var q *MyStruct2 = &MyStruct2{}
MyFunction(q)
也就是说,在实现接口的方法的接收器类型为非指针类型的情况下,参数类型为该接口的函数可以接受该类型的值作为指针或非指针类型的参数。