结构体
Go语言中将结构体与类可以说是合二为一了,这样其实也挺好的。
声明结构体需要使用关键字type和struct
type 结构体名称 struct{
名称 类型//属性
}
那么“类成员函数”该怎么创建呢。Go的类成员函数的创建方法和c++或是Java是不一样的,他的创建方法如下:
func (变量名称 结构体名称) PrintInfo() {
内容
}
如果希望像c++那样使用类属性或者修改它,在go中需要这样做:
type Student struct {
Name string
Age int
}
func (s Student) PrintInfo() {
fmt.Printf("name:%s age:%d\n", s.Name, s.Age)
}
在这里面,变量s替代了this关键字的作用,或者self关键字,这也就是为什么方法前面会跟着一个(s Student)。你当然也可以不叫s,你可以让他叫 this 或者 self 什么的,go 中给了程序员更大的自由。
公开属性/私有属性
在这里面,如果属性的首字母是大写,在go中意味着public。当然,如果属性的首字母是小写,在go中意味着private。
如下:
type Student struct {
Name string
age int
}
这段代码中,Name属性是公开的,在调用这个结构体时,可以直接通过Student.Name = xxx来修改值,而age是不能的,因为他首字母小写,是私有属性。
继承
在 go 中,既然结构体和类合并了,那么结构体自然也可以继承,那么语法是什么样的?如下:
type People struct {
Time string
}
type Student struct {
People //在这
Name string
Age int
}
在这里,Student类继承了People类。但实际上,由于Go本身的设计问题,这里的继承与C++和Java的继承是不一样的。我并没有提私有继承,亦或者是公有继承等等,这也是因为Go的继承更像是把父类的所有公开属性剪切到子类中去。没错,如果父类有私有属性的话,那么继承到子类时,子类不会拥有父类的私有属性,只会继承父类的公有属性,这一情况对方法也同样适用。
方法
虽然我在上面讲过Go中如何为结构体创建方法,但这里还有一个东西需要单独拿出来强调,那就是如果不以指针的形式绑定方法的话,你是不能在方法中修改结构体里面属性的值的。如下:
type Student struct {
Name string
Age int
}
func (s Student) SetAge(age int) {
s.Age = age
}
func (s *Student) SetAge1(age int) {
s.Age = age
}
这两个方法都对s的Age值作了修改,但实际执行中,只有SetAge1函数真的完成了对s的属性的修改,而SetAge方法,实际上只是在该方法内短暂地修改了Age,出了这个方法,就变回去了。
这些有趣的区别在rust等语言中也是一致的,我个人认为这是现代新式语言与传统面向对象语言在设计时的思路不同,它实际上更有意思,而且就我个人看来降低了设计面向对象代码时的复杂度。