在学习Go语言的过程中,基本的语法以及slice和map等等虽然略有不同,但是稍微适应下,还是比较好上手,这里针对几个特别的地方总结下。第一篇就是Go的方法和接口。
方法
Go语言不存在类的概念,所以方法与函数的区别就是方法存在接收者。接受者在 func 关键字和 方法名之间,下面就是两个例子。
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func ScaleFunc(v *Vertex, f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
func main() {
v := Vertex{3, 4}
v.Scale(2)
ScaleFunc(&v, 10)
p := &Vertex{4, 3}
p.Scale(3)
ScaleFunc(p, 8)
fmt.Println(v, p)
}
上面两个例子的接收者分别是值和指针。二者的区别类似函数间参数传递,采用值作为接收者改变的一般都是值的副本,而采用指针作为接收者可以更改指针指向的值。因为方法通常需要改变接收者,而且为了避免传递接受者反复copy值(如果接受者是很大的对象,会影响效率),所以采用指针作为接收者更为常见。
函数如果有一个指针类型的参数,那么它必须接受一个对应指针类型的参数,而方法则不同,拥有指针类型或者值类型接受者的方法既可以接受值作为接受者也可以接受指针作为接受者,因为go会自动对接受者进行适配。
接口
和其他语言一样,go的接口也是定义一组方法,不同的是go的接口是隐式实现的,没有显式的implements声明。如果某一类型实现了某个接口类型声明的一组方法,那么这个用户定义的类型的值就可以赋给这个接口类型的值,对接口方法的调用会执行对应用户定义的类型对应的方法。这样基于接口就可以实现多态。
未完待续……