Go 方法:一种没有类的面向对象式编程

引言

在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

你可能感兴趣的:(Go 方法:一种没有类的面向对象式编程)