结构和方法
- go 语言仅支持封装,不支持继承和多态
- go语言没有class,只有struct
结构定义
typedef TreeNode struct {
value int
left,right *treeNode
}
结构的创建
- 无论地址还是结构本身,一律用.来访问成员
root := TreeNode{value:3}
root.left = &TreeNode{}
root.right = &TreeNode{nil,nil,5}
root.right.left = new(TreeNode)
工厂函数代替构造函数
func creatNode(value int) *TreeNode {
return &TreeNode{value:value}
}
root.left.right = creatNode(2)
- 注意返回局部变量的地址,go语言支持返回局部变量
结构是创建在堆上还是栈上
- 不需要知道,有垃圾回收机制
- 由编译器决定
为结构体定义方法
func (node TreeNode) print() {
fmt.print(node.value)
}
//调用
root.print()
- 括号中的node 是接收者,相当于this指针
func print(node TreeNode) {
fmt.print(node.value)
}
//调用
print(root)
- 两者写法不一样,结果是一样的
使用指针作为方法接收者
func (node *TreeNode) setValue(value int) {
node.value = value
}
- 只有使用指针才可以改变结构内容
- nil指针也可以调用方法
值接收者 Vs 指针接收者
- 要改变内容必须使用指针接收者
- 结构过大也考虑使用指针接收者
- 一致性:如有指针接收者,最好都是指针接收者
- 值接收者是go语言特有
- 值/指针接收者均可接收值/指针
封装
- 名字一般使用CamelCase
- 首字母大写:public
- 首字母小写:private
包
- 每个目录一个包
- main包包含可执行入口
- 为结构定义的方法必须放在一个包内,可以是不同文件
扩展已有类型
如何扩展系统类型或者别人的类型
- 定义别名
package queue
type Queue [] int
func (q *Queue) Push(v int) {
*q = append(*q, v)
}
func (q *Queue) Pop() int {
head := (*q)[0]
*q = (*q)[1:]
return head
}
func (q *Queue) IsEmpty() bool {
return len(*q) == 0
}
package main
import (
"awesomeProject/queue"
"fmt"
)
func main() {
q := queue.Queue{1}
q.Push(2)
q.Push(3)
fmt.Println(q.Pop())
fmt.Println(q.Pop())
fmt.Println(q.IsEmpty())
fmt.Println(q.Pop())
fmt.Println(q.IsEmpty())
}
- 使用组合
type TreeNode struct {
Value int
Left,Right *TreeNode
}
type myTreeNode struct {
node *tree.TreeNode
}
func (myNode *myTreeNode) postOrder(){
if myNode == nil || myNode.node == nil {
return
}
left := myTreeNode{myNode.node.Left}
right := myTreeNode{myNode.node.Right}
left.postOrder()
right.postOrder()
myNode.node.Print()
}
- 使用内嵌来扩展已有类型
package tree
import "fmt"
type TreeNode struct {
Value int
Left,Right *TreeNode
}
type myTreeNode struct {
*tree.TreeNode // Embedding 内嵌
}
func (myNode *myTreeNode) postOrder(){
if myNode == nil || myNode.TreeNode == nil {
return
}
left := myTreeNode{myNode.Left}
right := myTreeNode{myNode.Right}
left.postOrder()
right.postOrder()
myNode.Print()
}