func(c cats) say() { fmt.Println("Fish~") } func(d dogs) say() { fmt.Print("Shit~") } funcsayer(s say) { // 接受一个参数,进来什么,什么就调用它的speak s.say() } funcmain() { var x say a := cats{} b := dogs{} x = a x.say() x = b x.say() }
type moving interface { move() } type dog struct{} type cat struct{}
func(d dog) move() { fmt.Println("丁丁~") }
func(c cat) move() { fmt.Println("喵呜~") } funcmove(m moving) { // 接受一个参数,进来什么,什么就调用它的speak m.move() } funcmain() { var x moving a := dog{} b := &cat{} x = a x.move() x = b x.move() }
从上面的代码中我们可以发现,使用值接收者实现接口之后,不管是 dog 结构体还是结构体指针 * dog 类型的变量都可以赋值给该接口变量。因为 Go 语言中有对指针类型变量求值的语法糖,cat 指针 x 内部会自动求值 (* ** x)
type moving interface { move() } type dog struct{} type cat struct{}
func(d dog) move() { fmt.Println("丁丁~") }
func(c *cat) move() { fmt.Println("喵呜~") } funcmove(m moving) { // 接受一个参数,进来什么,什么就调用它的speak m.move() } funcmain() { var x moving a := dog{} // a是dog类型 x = a // 可以接收dog类型 x.move() b := cat{} x = b // 不可以接受指针类型 x.move() } // # command-line-arguments // ./pointer.go:28:4: cannot use b (type cat) as type moving in assignment: // cat does not implement moving (move method has pointer receiver)
v1.5.2