遥想写js
时,写方法跟写属性一样so easy
。但是在学go
的时候,妈妈有点担心了。
// goinaction中的一个例子
func main() {
var b bytes.Buffer
b.Write([]byte("hello"))
fmt.Fprintf(&b, "world")
io.Copy(os.Stdout, &b)
}
因为不熟,在敲这段代码的时候,我把fmt.Fprintf(&b, "world")
敲成了fmt.Fprintf(b, "world")
,然后竟然报错了。
然后我就万脸茫然?
记得学struct
的时候,可以这样实现方法的:
type Person struct {
name string
}
func (p *Person) sayHi() {
fmt.Println(p.name + " hello world")
}
func main() {
p := Person{"zhazha"}
p.sayHi() // zhazha hello world
// 或者
(&p).sayHi()
}
为什么fmt.Fprintf(&b, "world")
只能传入&b
呢?
竟然这一节讲interface
,那肯定跟interface
有关系?写个小demo测试一下
// 随便定义了一个interface
type Hier interface {
sayHi()
}
type Person struct {
name string
}
// 实现了Hier的接口
func (p *Person) sayHi() {
fmt.Println(p.name + " hello world")
}
// 这里的方法传入的是一个实现Hier接口的值
func someFuncTakePPoint(h Hier) {
h.sayHi()
}
func main() {
p := Person{"zhazha"}
// 果然
someFuncTakePPoint(&p)
// 这里如果用p作参数,会编译出错
// cannot use p (variable of type Person) as Hier value in argument to someFuncTakePPoint
// someFuncTakePPoint(p)
}
Recap:
- 如果方法的接受者是
struct
的指针类型,可以用值或者值的指针调用该方法。可实现的原因是编译器会帮忙处理。 - 如果结构体实现了
interface
,即实现了interface
定义的方法,且这个方法的接收者是指针类型时,在使用这个结构体作为接口类型的参数时,只能用值的指针。