💭

Goで初期化した構造体を宣言する方法

2024/06/16に公開

初期化した構造体を宣言してデータベースの操作をするときに、型宣言やらアドレスやらポインタやらでこんがらがったのでまとめます。

Goの型宣言について

前提として、Goで型宣言をすると、自動でそのかたのゼロ値を代入してくれるみたいです。

var 宣言は特定の方の変数を作成し、その変数に名前を結びつけて初期値を設定します。
初期値はその方に対するゼロ値(zero value)であり、数値なら0、ブーリアンならfalse、文字列なら””、インターフェースと参照型(スライス、ポインタ、マップ、チャネル、関数)ならnilです。

プログラミング言語Go

var (
	i int
	s string
	b bool
	v interface{}
)

fmt.Println(i, s, t, v) // 0 "" false nil

構造体をゼロ値で宣言する方法

例えば以下のようなUser構造体があり、新たにCreateUser()したい場合などを想定します。

type User struct {
    ID       int
    Username string
}

新たなUserを作成するために初期化された構造体を用意するかと思いますが、型宣言をするか、初期化した構造体のポインタを用意して代入するか、User型を指すポインタ型を宣言するかで多少初期化のされ方が異なります。

自分はこの辺で頭が???になったので、以下のコードを用意してそれぞれの出力の違いを見るのがわかりやすいと思います。

package main

import "fmt"

type User struct {
	ID       int
	Username string
}

func main() {
	var (
		user  User  // userはUser型とであると宣言
		pUser *User // User型を指すためのポインタ型であると宣言
	)
	addUser := &User{} // User構造体を初期化したポインタを代入

	fmt.Printf("user: %+v\npUser: %+v\naddUser: %+v\n", user, pUser, addUser)
}

出力は以下のようになります。

user: {ID:0 Username:} # User構造体の初期値
pUser: <nil> # User構造体の初期値を指すポインタの初期値
addUser: &{ID:0 Username:} # User構造体の初期値のポインタ
  • addUserUser構造体を初期化したポインタを代入したのでそのまま出力されています。

  • userpUserは型宣言しただけですが、Goが勝手にその型の初期値を代入してくれているので、こちらもそれぞれの初期値が出力されています。

まとめ

Goは型宣言すると自動でその型のゼロ値を代入してくれます。このおかげでいろいろエラーを防いでくれるみたいです。自分はまだその恩恵を受けるレベルに達していませんが。。。笑

参考にした「プログラミング言語Go」はC言語の名著「プログラミング言語C」の作者Brian W. Kernighanさんが書いたとのことで、Goの本質が体系的にまとまっており、辞書的に使わせて頂いております。今回みたいな痒いところにも手が届くので、Goを使用するエンジニアは持っていて損することはないと思っています!

Discussion