GO語言筆記--結構體

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)一致性,如果有指針接收者最好使用指針接收者

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章