引言
在Go中没有class 关键词,但是有方法的概念。以前不知道在哪里读到过,说编程最重要的就是两个核心:数据结构和算法。在Go中,没有一个class 关键字来把对象模板的数据和对数据操作的方法包起来。如果将type 和 struct 当为Go中数据的包,那么方法就是拆包器。
方法的定义
方法说白了也就是多了一个“接收者” 的函数,最简单"包"和“拆包器”的定义:
type Cube struct{
width float32
length float
height float
}
func (cube Cube) Area () float32{
// |------> 接收者
return cube.width * cube.length * cube.height
}
接受者使用指针还是直接值
《Go Programming Language》P158页,"calling a function makes a copy of each argument value, if a function needs to update a variable, of if an argument is so large that we wish to avoid copying it, we must pass the address of the variable using a pointer."
也就是说,调用方法其实也是函数调用,如果没有用指针参数,则调用时,参数会被复制一个copy传递入函数体内。当你需要修改结构体内部的某个值时,如果是通过写方法的方式,那么方法的接受者需要使用指针。假设要让上面的Cube对象完成形如 c.set(1.2,2.0,3.0)
的操作,可以将接受者定义为指针类型的
func (self *Cube) set(width float32, length float32, height float32){
self.width = width
self.length = length
self.height = height
}
这里我故意用 self 这个变量名,但是其实是可以任意的变量名。眼尖的朋友可能立即观察到,上面的代码好像有bug, 不是应该写成 (*self).width=width
吗?其实两者是通用的。当你的代码中使用self.width
时, 编译器会自动把它转变为(*self).width
,编译器为什么这么聪明?因为Go时强类型语言,上面的self变量是指针型变量,对它进行点操作(.)其实语义上是很明确的,这种变换,其实是一种语法糖.
如果没有用指针直接这样定义:
// THIS IS WRONG!!
func (self Cube) set(width float32, length float32, height float32){
....
}
虽然接受者还是叫self,但是其实它是 self 的copy,你用 c.set(1.2,2.0,3.0)
去设置 c
的值,c
纹丝不动,因为调用时,被默默的被修改的只是c
的影子拷贝。
另外一个方面,前面的那个接收者是指针的代码,你指望着 c.set(1.2,2.0,3.0)
语句编译器帮你报错,应当是(*c).set(....)
才对, 是不是?但是其实没有错误跳出来,原因也是上面所说的编译器使用的 语法糖
本篇完
初学者,请多指教
原创内容,转载请注明 copywrite threadtag