1.說明
1)go中的struct與C中的struct非常相似,並且go沒有class
2)使用type <Name> struct {}定義結構,名稱遵循可見性規則
3)支持指向自身的指針類型成員
4)支持匿名結構,可用作成員或定義成員變量
5)匿名結構也可以用於map的值
6)可以使用字母值對結構體進行初始化
7)允許直接通過指針類讀寫結構成員
8)相同類型的成員可以進行直接拷貝賦值
9)支持==與!=比較運算符,但不支持>或<
10)支持匿名字段,本質上是定義了以某個類型名爲名稱的字段
11)嵌入結構作爲匿名字段看起來像繼承,但不是繼承
12)可以使用匿名字段指針
13)go語言僅支持封裝,不支持繼承和多態
14)go沒有class,只有struct
實例,創建一棵樹的數據結構
package main
import "fmt"
type treeNode struct {
value int
left, right *treeNode
}
func main() {
var root treeNode
//初始爲空
fmt.Println(root)
//幾種不同的創建樹的方法
root = treeNode{value: 3}
root.left = &treeNode{}
root.right = &treeNode{5, nil, nil}
root.right.left = new(treeNode)
nodes := []treeNode{
{value: 3},
{},
{6, nil, &root},
}
//打印查看創建的結構
fmt.Println(nodes)
}
輸出:
API server listening at: 127.0.0.1:36962
{0 <nil> <nil>}
[{3 <nil> <nil>} {0 <nil> <nil>} {6 <nil> 0xc0420503e0}]
2.工廠函數
//go語言結構中沒有構造函數,但是可以創建一個工廠函數來負責創建結構
func createNode(value int) *treeNode {
//go語言中返回一個局部變量的地址是可以給外部使用的
return &treeNode{value: value}
}
root.left = createNode(100)
實例:
package main
import "fmt"
type treeNode struct {
value int
left, right *treeNode
}
func (node treeNode) print() {
fmt.Println(node.value)
}
//go語言結構中沒有構造函數,但是可以創建一個工廠函數來負責創建結構
func createNode(value int) *treeNode {
//go語言中返回一個局部變量的地址是可以給外部使用的
return &treeNode{value: value}
}
func (node treeNode) setVale(value int) {
node.value = value
node.print()
}
func (node *treeNode) setValePtr(value int) {
node.value = value
node.print()
}
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.print() //這裏有個接收者,root相當於參數,值傳遞
root.right.print()
root.right.left.print()
root.left.right.print()
fmt.Println()
//檢驗接收者值傳遞,傳入一個值在局部打印,之後在主函數打印觀察是否被修改
fmt.Println("#####################")
root.right.left.print()
root.right.left.setVale(100)
root.right.left.print()
//地址傳入測試,這樣發現內容會被修改
fmt.Println("#####################")
root.right.left.print()
root.right.left.setValePtr(100)
root.right.left.print()
}
輸出:
5
0
2
#####################
0
100
0
#####################
0
100
100
上述發現,只有指針傳入的時候內容纔會被修改,其他值專遞情況不會修改內容,這裏可以總結爲:
1)只有使用指針纔可以改變結構內容
3)nil指針也可以調用方法
實例:遍歷一棵樹
package main
import "fmt"
type treeNode struct {
value int
left, right *treeNode
}
func (node treeNode) print() {
fmt.Printf("%d ", node.value)
}
//go語言結構中沒有構造函數,但是可以創建一個工廠函數來負責創建結構
func createNode(value int) *treeNode {
//go語言中返回一個局部變量的地址是可以給外部使用的
return &treeNode{value: value}
}
//中序遍歷
func (node *treeNode) traverse() {
if node == 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)
//遍歷樹
root.traverse()
}
輸出:
API server listening at: 127.0.0.1:33038
0 2 3 0 5
接收者總結,指針接收者和值接收者應該如何使用
1)要改變內容必須使用指針接收者
2)結構過大也考慮使用指針接收者
3)一致性,如果有指針接收者最好使用指針接收者