Go

Golang 構造体と仲良くなろう


目的

golangの構造体に慣れるためのメモです。


複数の構造体が入っている配列を作成してjsonに変換してみる


sample.go

package main

import (
"encoding/json"
"fmt"
)

type Animal struct {
Name string
Age int
}

type Animals []Animal

func main() {
// Animal構造体初期化
var inu Animal = Animal {
Name: "わんわん",
Age: 3,
}

// こっちの書き方でも初期化できる
neko := Animal {
Name: "にゃんにゃん",
Age: 8,
}

// 配列宣言
var animals Animals

// 配列にinuとnekoを追加する
animals = append(animals, inu)
animals = append(animals, neko)

fmt.Println(animals)
// ⇛ [{わんわん 3} {にゃんにゃん 8}]

// 配列をjsonに変換する
b, _ := json.Marshal(animals)
fmt.Printf("%s\n", b)
// ⇛ [{"Name":"わんわん","Age":3},{"Name":"にゃんにゃん","Age":8}]
}



ポインタと値の挙動


struct.go

package main

import "fmt"

type Animal struct {
Name string
Age int
}

type Animals []Animal

func main() {
fmt.Println("patternA")
patternA()

fmt.Println("patternB")
patternB()

fmt.Println("patternC")
patternC()

fmt.Println("patternD")
patternD()

fmt.Println("patternE")
patternE()
}

func patternA() {
cat1 := &Animal{} // &ついているんで、ポインタ
fmt.Println(cat1)
fmt.Println(*cat1) // * つけてアクセスしたので値を示す

// =>
//&{ 0}
//{ 0}
}

func patternB() {
cat1 := &Animal{}

fmt.Println(cat1) // &ついてるんで、ポインタ
fmt.Println(*cat1) // * つけてアクセスしたので値を表す

cat2 := cat1
fmt.Println(cat1) // &ついてるんで、ポインタ
fmt.Println(cat2) // cat1を代入した変数なので、ポインタ

cat2.Name = "catty" // ポインタを渡した別変数でフィールド書き換え
fmt.Println(cat1)
fmt.Println(cat2)

// =>
// &{ 0}
// { 0}
// &{ 0}
// &{ 0}
// &{catty 0}
// &{catty 0}
}

func patternC() {
cat1 := &Animal{}

fmt.Println(cat1) // &ついてるんで、ポインタ
fmt.Println(*cat1) // *つけてアクセスしているので、値を表す

cat2 := *cat1 // 値をcat2に代入
fmt.Println(cat1) // ポインタ
fmt.Println(cat2) // 値

cat2.Name = "catty" // フィールドを書き換える

fmt.Println(cat1) // 値を渡した元の変数は変化しない
fmt.Println(cat2)

// =>
// &{ 0}
// { 0}
// &{ 0}
// { 0}
// &{ 0}
// {catty 0}
}

func patternD() {
// アドレス演算子をつけて初期化したパターン(cat1 := &Animal{})と同じ挙動
cat1 := new(Animal) // ゼロ初期化。

fmt.Println(cat1) // &ついてるんで、ポインタ
fmt.Println(*cat1) // *つけてアクセスしてるんで、値

cat2 :=cat1 // ポインタを別変数に代入

fmt.Println(cat1)
fmt.Println(cat2)

cat2.Name = "catty" // ポインタを渡した別変数でフィールド書き換え
fmt.Println(cat1)
fmt.Println(cat2)

// =>
// &{ 0}
// { 0}
// &{ 0}
// &{ 0}
// &{catty 0}
// &{catty 0}

}

func patternE() {
// アドレス演算子をつけて初期化したパターン(cat1 := &Animal{})と同じ挙動
cat1 := new(Animal) // ゼロ初期化。

fmt.Println(cat1) // &ついてるんで、ポインタ
fmt.Println(*cat1) // *つけてアクセスしてるんで、値

cat2 := *cat1 // 値を別変数に代入

fmt.Println(cat1) // ポインタ
fmt.Println(cat2) // 値

cat2.Name = "catty" // フィールド書き換え
fmt.Println(cat1) // ポインタは変わらない
fmt.Println(cat2) // 値は変わる

// =>
// &{ 0}
// { 0}
// &{ 0}
// { 0}
// &{ 0}
// {catty 0}

}