LoginSignup
0
1

More than 3 years have passed since last update.

【Golang】Go言語の基礎 構造体について①

Posted at

Goにはオブジェクトと呼ばれるものはありません。したがって、クラスという概念が存在しないです。
その代わりに構造体というものがあり、オブジェクト指向のような書き方をすることが可能です。

まずは第一弾として構造体の書き方や初期化の方法などについてみていきます。

②では構造体の埋め込み(オブジェクト指向でいう継承のようなもの。Goには継承はありません。)について書いていこうと思ってます!

構造体を使ってあれこれ書いてみる

構造体は type と structを用いて書くことができます。


package main

import "fmt"

type Vertex struct {
    X int
    Y int //小文字のyにすると外部からアクセスできなくなる
    S string
}

func main() {
    //構造体の初期化
    v := Vertex{X: 1, Y: 2}
    fmt.Println(v) // => {1 2}

    //構造体のフィールドにアクセス
    fmt.Println(v.X, v.Y) // => 1 2

    //中身を書き換える
    v.X = 100
    fmt.Println(v.X, v.Y) // => 100 2

    //このように一部の値を渡すこともできる。その場合、残りはデフォルトの値が入る。(intは0、stringは空文字)
    v2 := Vertex{X: 1}
    fmt.Println(v2) // => {1 0 }

    //構造体に書いてる順番通りに書いてフィールドの値を渡して初期化することもできる
    v3 := Vertex{1, 2, "huga"}
    fmt.Println(v3) // => {1 2 huga}

    //{}で空の構造体を宣言 それぞれの型のデフォルトの値が入る
    v4 := Vertex{}
    fmt.Println(v4) // => {0 0 }
    fmt.Printf("%T %v\n", v4, v4) // => main.Vertex {0 0 }

    //varで宣言だけした場合はv4と同じ構造体になる。mapやスライスは宣言だけした場合はnilになるので注意。
    var v5 Vertex 
    fmt.Println(v5) // =>{0 0 }
    fmt.Printf("%T %v\n", v5, v5) // =>main.Vertex {0 0 }

    //ポインタが返ってくる
    v6 := new(Vertex)
    fmt.Println(v6) // => &{0 0 }
    fmt.Printf("%T %v\n", v6, v6) // => *main.Vertex &{0 0 }

    //ポインタが返ってくる、この書き方だと一目でポインタが返ってくるとわかるのでこちらを使うことが多いようです!
    v7 := &Vertex{}
    fmt.Println(v7) // => &{0 0 }
    fmt.Printf("%T %v\n", v7, v7) // => *main.Vertex &{0 0 }

}

&を付けてアドレスで引数を渡すと最初に定義した値を書き換えることができる。


package main

import "fmt"

type Vertex struct {
    X int
    Y int //yにするとアクセスできなくなる
    S string
}

func changeVertex(v Vertex) {
    v.X = 1000
}
func changeVertex2(v *Vertex) {
    v.X = 1000
}

func main() {
    v := Vertex{1, 2, "hoge"}
//値私なので、宣言した元の構造体は書き換わらない。
    changeVertex(v)
    fmt.Println(v) {1 2 hoge}

//ポインタ渡しなので元の構造体を書き換えることができる。
    v2 := &Vertex{1, 2, "hoge"}
    changeVertex2(v2)
    fmt.Println(v2)&{1000 2 hoge}
}

なぜポインタ渡しを使うのか?

・値渡しと違って、間接的に参照・操作できる

・上で見たように値渡しだと関数の引数として構造体を渡した場合に、その構造体のコピーが生成されてしまい、元の構造体に影響を与えない。ポインタ渡しだと影響を与えることができる。

・単純にORマッパーなどのライブラリがポインタを使うので使わざるを得ない

・大きな構造体を値渡しするとコピー処理で性能が劣化する。 ポインタ渡しの場合には固定で8バイト>(64bit)/4バイト(32bit)なので性能が劣化しない。

引用元:Golangのポインタ渡し初心者を卒業した

との理由からのようです。初学者の自分にはいまいちピンときませんw
実践で使っていく中で腹で理解していけばいいと思っています。
とりあえずこんなことができるということをまずは頭に叩き込もうと思います!

0
1
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
0
1