GO言語メモ--構造体


1.説明
1)go中のstructはC中のstructと非常に似ており,goにはclassはない
2)type 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  }
[{3  } {0  } {6  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ポインタもメソッドを呼び出すことができる
 
例:1本の木を巡る
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)一貫性、ポインタ受信者があればポインタ受信者を使用することが望ましい