LoginSignup
23

More than 5 years have passed since last update.

Golang 構造体と仲良くなろう

Last updated at Posted at 2016-06-29

目的

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}

}

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23