go面向对象

go 仅支持封装,不支持继承和多态

Go 没有 class,只有 struct

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
type treeNode struct {
value int
left, right *treeNode
}

// go可以将局部变量返回给外部使用,跟js很像
func createTreeNode(val int) *treeNode {
return &treeNode{value: val}
}

var root treeNode
root = treeNode{value: 3}
root.left = &treeNode{}
root.right = &treeNode{5, nil, nil}
root.right.left = new(treeNode) // new内建函数,返回treeNode的地址
root.right.left.right = createTreeNode(12) //不需要了解局部变量是分配在栈还是堆

nodes := []treeNode{
{value: 3},
{},
{value: 5, left: nil, right: nil},
{5, nil, &root},
}

fmt.Println(nodes)

为 struct 定义方法

  1. 编译器会自行判断方法需要的是值还是指针
  2. 值接受者和指针接受者
  3. 指针储存的是一个值的地址,但本身这个指针也需要地址来储存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

func (node treeNode) print() {
fmt.Print(node.value)
}

// 编译器会自行判断方法需要的是值还是指针,
// 需要实例的指针传递进来,才能改变实例的属性值
func (node *treeNode) setVal(val int) treeNode { //指针接收者里的 *treeNode 代表的是类型
if node == nil {
fmt.Printf("node is not exist")
return
}
node.value = val
return *node // 在这里*node不再代表类型,而是表示node指针所指向的值 如果单纯返回node,那它的类型就是*treeNode,而返回*node就是返回node的值(类型为treeNode)
}


var node = treeNode{value: 1}
node.setVal(25) // 调用时会将地址传递进方法内
node.print() // 调用时会将值copy

// 直接使用.调用方法会报错,因为treeNode{value: 1}返回的是值,需要取对象的引用地址来调用方法
var node2 = (&treeNode{value: 1}).setVal(5)
node2.print()

// new方法可以直接返回构建对象的指针
// func new(Type) *Type
var node3 = new(treeNode).setVal(15)
node3.print()

// 值为nil也可以调用类型的方法
var node2 *treeNode
node2.setVal(200)

&T{}相当于 new(T)