结构体和方法
package main
import "fmt"
type treeNode struct {
value int
left, right *treeNode
}
//工厂函数
func createNode(treeValue int) *treeNode {
// 返回了局部变量
return &treeNode{value: treeValue}
}
func (node treeNode) print() {
fmt.Println(node.value)
}
func (node *treeNode) setValue(value int) {
if node == nil {
fmt.Println("node.value is nil to setting.ignore")
return
}
node.value = value
}
func (node *treeNode) traverse() {
if node == nil {
fmt.Println("node is nil")
return
}
node.left.traverse()
node.print()
node.right.traverse()
}
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)
fmt.Println(*root.left.right)
nodes := []treeNode{
{value: 3},
{},
{6, nil, &root},
}
fmt.Println(nodes)
root.print()
fmt.Println(root.right.left.value)
root.right.left.setValue(4)
fmt.Println(root.right.left.value)
root.print()
root.setValue(100)
pRoot := &root
pRoot.print()
pRoot.setValue(2)
pRoot.print()
// var testRoot *treeNode
// testRoot.setValue(20)
// // testRoot.print()
// testRoot = &root
// testRoot.setValue(20)
// testRoot.print()
root.traverse()
}
- 不论地址还是结构本身,一律使用.来访问成员
- 不需要知道go中的结构体是创建在堆上还是栈上,到最后都由垃圾回收机制进行回收
- 只有用指针才能改变结构内容
- nil指针也可以调用方法
- 要改变内容必须使用指针接收者
- 结构过大也考虑使用指针接收者
- 一致性:如有指针接收者,最好都是指针接收者
- 值接受者是go特有的
封装
package tree
import (
"fmt"
"reflect"
)
type TreeNode struct {
value int
left, right *TreeNode
}
//工厂函数,首字母改大写,变public
func CreateNode(treeValue int) *TreeNode {
// 返回了局部变量
return &TreeNode{value: treeValue}
}
//首字母小写,private
func (node TreeNode) print() {
fmt.Println(node.value)
}
//首字母小写,private
func (node *TreeNode) setValue(value int) {
if node == nil {
fmt.Println("node.value is nil to setting.ignore")
return
}
node.value = value
}
//首字母大写,public
func (node *TreeNode) Traverse() {
if node == nil {
fmt.Println("--------------------")
fmt.Println(reflect.TypeOf(node))
fmt.Println("node is nil")
fmt.Println("--------------------")
return
}
node.left.Traverse()
node.print()
node.right.Traverse()
}
- 首字母大写代表piblic
- 首字母小写代表private
- 名字一般使用CamelCase
- 每个目录一个包,包名可以和目录名不一样——import只是导入相对GOPATH/GOROOT的路径,路径下的包是在代码中被调用的,跟路径没关系,同一个目录只能有一个包
- main包包含可执行入口
- 为结构定义的方法必须放在同一个包内
- 可以是在同一目录下的不同文件
- go一般不使用全小写或者带下划线的形式
包
main.go
package main
import (
// 若包名与路径下文件夹名称不一样,需要在路径前面写出对应的包名
queue "ZipTest_backend/queue_test"
"fmt"
)
func main() {
q := queue.Queue{1}
q.Push(2)
q.Push(3)
fmt.Println(q)
fmt.Println(q.Pop())
fmt.Println(q.Pop())
fmt.Println(q.IsEmpty())
fmt.Println(q.Pop())
fmt.Println(q.IsEmpty())
}
queue.go
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 {
if len(*q) == 0 {
return true
}
return false
}
- 为结构定义的方法必须放在同一个包内
- 可以是不同文件
使用内嵌来扩展已有的类型
main.go
package main
import (
"ZipTest_backend/tree"
"fmt"
)
type myTreeNode struct {
*tree.Node //embeding 内嵌
}
func (myNode *myTreeNode) postOrder() {
// 如果node为空,则直接返回
if myNode == nil || myNode.Node == nil {
return
}
left := myTreeNode{myNode.Left}
right := myTreeNode{myNode.Right}
left.postOrder()
right.postOrder()
myNode.Print()
}
//Traverse 重载
func (myNode *myTreeNode) Traverse() {
fmt.Println("this method is shadowed")
}
func main() {
root := myTreeNode{&tree.Node{Value: 3}}
root.Left = &tree.Node{} //Value = 0
root.Right = &tree.Node{5, nil, nil}
root.Right.Left = new(tree.Node)
root.Left.Right = tree.CreateNode(2)
root.Right.Left.SetValue(4)
fmt.Print("root.traverse: traversal:")
root.Traverse()
fmt.Print("root.Node.traverse: traversal:")
root.Node.Traverse()
fmt.Print("My own post-order traversal:")
root.postOrder()
fmt.Println()
// var baseRoot *tree.Node
var baseRoot *myTreeNode
baseRoot = &root // 类型必须一样才可以赋值
fmt.Println(baseRoot)
}
tree.go
package tree
import (
"fmt"
)
type Node struct {
Value int
Left, Right *Node
}
func (node *Node) Print() {
fmt.Print(node.Value)
}
//工厂函数,首字母改大写,变public
func CreateNode(treeValue int) *Node {
// 返回了局部变量
return &Node{Value: treeValue}
}
//首字母大写,public
func (node *Node) SetValue(value int) {
if node == nil {
fmt.Println("node.value is nil to setting.ignore")
return
}
node.Value = value
}
//首字母大写,public
func (node *Node) Traverse() {
if node == nil {
return
}
node.Left.Traverse()
node.Print()
node.Right.Traverse()
}
- go语言没有继承
- 只有当确保能够省下很多代码的时候才使用内嵌