go语言仅支持封装,不支持继承和多态。
go语言没有class,只有struct。
定义struct
struct声明:
type 标识符 struct {
field1 type
field2 type
}
示例:
type treeNode struct {
value int
left,right *treeNode
}
func main() {
var root treeNode
fmt.Println(root)
}
运行结果如下:
初始化默认值value是0,left和rigth都是nil
结构的创建
type treeNode struct {
value int
left,right *treeNode
}
func main() {
var root treeNode
root = treeNode{value:3}
root.left = &treeNode{}
root.right = &treeNode{6,nil,nil}
root.right.left = new(treeNode)
nodes := []treeNode{
{value:8},
{},
{6,nil,&root},
}
fmt.Println(nodes)
}
运行结果如下:
不论地址还是结构本身,一律使用.来访问成员
工厂函数
go语言没有构造函数,但是有时我们又想要使用构造函数咋办,我们可以使用工厂函数,工厂函数就是一些普通的函数,工厂函数返回一个指针
示例:
func createNode(value int) *treeNode {
return &treeNode{value:value}
}
此时,在函数createNode函数中,treeNode{value: value}是一个局部变量,然后返回的是一个局部变量的地址。
使用工厂函数创建一个节点
package main
type treeNode struct {
value int
left,right *treeNode
}
func createNode(value int) *treeNode {
return &treeNode{value:value}
}
func main() {
var root treeNode
root = treeNode{value:3}
root.left = &treeNode{}
root.right = &treeNode{5,nil,nil}
root.right.left = new(treeNode)
root.left.right = createNode(2)
}
最后一行代码root.left.right = createNode(2),注意:
- 使用了自定义工厂函数
- 返回了局部变量的地址
结构是创建在堆上还是栈上?
不需要知道,它反正后面有垃圾回收器,这个由go语言的编译器和运行环境决定的。
比如说treeNode局部变量没有取地址并返回出去,编译器很可能认为这个变量不需要给外部使用,就在栈上分配。如果treeNode取了地址并返回出去给别人使用,此时treeNode会分配到堆上,堆上分配完了之后这个treeNode就会参与垃圾回收,外面拿着这个指针的人就会做事情,等他做完了,把这个指针扔掉不用了,他就会被回收掉。
我们最后创建的树结构;
为结构定义方法
GO的方法是下定义在一个接收者上的一个函数,接收者是某种类型的变量;
GO的方法其实就是一个变种的函数
func (接收者) 函数名... 正常的函数结构
结合上面的结构,我们来定义方法,其实就是一个最基本的面向对象的雏形
func (node treeNode) print(){
fmt.Print(node.value)
}
值接收者VS指针接收者
- 要改变内容必须使用指针接收者
- 结构过大也考虑使用指针接收者
- 一致性:如果有指针接收者,最好都是指针接收者