夢のかけら

Goエンジニアの技術ブログ

【Golang】構造体はなぜポインタ型に値を代入できるのか

f:id:lampler:20210928210714j:plain

構造体がわからない

↓のような超絶簡単なコードだが、どうもしっくりこなかった。

type Person struct {
    Name  string
    Age   int
}

func main() {
    lamp := new(Person)
    fmt.Println(lamp)  // => &{ 0} (ポインタ型)

    lamp.Name = "lamp" // どうしてポインタに代入できるの!?
    fmt.Println(lamp)  // => &{lamp 0}
}

lamp.Name = "lamp" ここがよくわからない。ポインタとは変数の型と変数が格納されているメモリのアドレスのこと。 このコードは変数の実態に直接代入しているように見える。

これなら理解できる

lamp := Person{}
lamp.Name = "lamp"
fmt.Println(lamp) // => {lamp 0}

結論:おそらくGoの省略記法

これは省略記法ではないかと思う。(ソースを見つけられていないので真実は不明)

lamp := new(Person)
fmt.Println(lamp)  // => &{ 0} (ポインタ型)
fmt.Println(*lamp) // => { 0}
(*lamp).Name = "lamp"
fmt.Println(lamp) // => &{lamp 0}

省略せずに書くと (*lamp).Name = "lamp"だが、 lamp.Name = "lamp"でもOKになってるのではないだろうか。

配列へのポインタ

配列でも同じことが起こる。 ↓のコードではpがポインタ型であることをコンパイラが検知して、自動的に (*p)[0]に変換してくれる。

p := &[3]string{"a", "b", "c"}
fmt.Println(p[0])    // => a (省略記法)
fmt.Println((*p)[0]) // => a (こちらが本来の書き方)