我正在学习接口(interface),类型转换和带有指针接收器的方法。
指针接收器方法背后的规则和术语使我感到困惑。
让我展示我对一个程序的困惑。
这是我的Go程序。
package main
import "fmt"
type Employee struct {
Name string
}
func (e Employee) Hi() {
fmt.Printf("Hi! I am %s.\n", e.Name)
}
func (e *Employee) Hello() {
fmt.Printf("Hello! I am %s.\n", e.Name)
}
func main() {
var a Employee = Employee{"Alice"}
a.Hi()
a.Hello()
var b interface{} = Employee{"Bob"}
b.(Employee).Hi()
// b.(Employee).Hello()
}
这是输出。
Hi! I am Alice.
Hello! I am Alice.
Hi! I am Bob.
如果删除最后注释的行,则会出现此错误。
# command-line-arguments
./foo.go:24: cannot call pointer method on b.(Employee)
./foo.go:24: cannot take the address of b.(Employee)
如何修复该行代码,以便能够使用
指针接收器?请解释一个解决方案,并说明原因
通过使用指针接收器放下方法的概念无法正常工作。
最佳答案
您不能(在这种情况下,对于指针接收器来说是隐式的)获取表达式结果的地址(b.(Employee)
)。您可以获取变量的地址。例如,
package main
import "fmt"
type Employee struct {
Name string
}
func (e Employee) Hi() {
fmt.Printf("Hi! I am %s.\n", e.Name)
}
func (e *Employee) Hello() {
fmt.Printf("Hello! I am %s.\n", e.Name)
}
func main() {
var a Employee = Employee{"Alice"}
a.Hi()
a.Hello()
var b interface{} = Employee{"Bob"}
b.(Employee).Hi()
// b.(Employee).Hello()
// main.go:24: cannot call pointer method on b.(Employee)
// main.go:24: cannot take the address of b.(Employee)
e := b.(Employee) // e, a variable, is addressable
e.Hello()
var c interface{} = &Employee{"Chris"}
c.(*Employee).Hi()
c.(*Employee).Hello()
}
输出:
Hi! I am Alice.
Hello! I am Alice.
Hi! I am Bob.
Hello! I am Bob.
Hi! I am Chris.
Hello! I am Chris.
断言
b.(Employee)
类型的值是Employee
类型。方法调用b.(Employee).Hello()
是(&b.(Employee)).Hello()
的简写,因为func (e *Employee) Hello()
具有指针接收器。但是,表达式b.(Employee)
是不可寻址的。所以,error: cannot call pointer method on b.(Employee)
error: cannot take the address of b.(Employee)
关于pointers - 类型断言后如何使用指针接收器调用方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43883502/