構造体の初期化を楽にするGoのコンストラクタパターン

Go言語
この記事は約5分で読めます。
Go初学者
Go初学者

Go言語にはコンストラクタの機能はないの?

この記事では構造体の初期化を楽にするパターンを知ることができます!
  • コンストラクタのパターンを実装する
  • 通常の構造体の初期化との比較

オブジェクト指向プログラミングでは、class で作成されたオブジェクトの生成と初期化のための特殊なメソッドとしてコンストラクタという機能があります。

Go言語では class が無いので、コンストラクタの機能がありません。

ですが、Goのプログラムではパターンとしてコンストラクタの機能に似たコードをよく見かけますので紹介します。

構造体の定義に不安な方は、当ブログの下記の記事が参考になります。

もりぴ
この記事を書いた人

XHTML1.0時代にHTML&CSSを勉強した経験あり。無趣味だった私が2020年5月からプログラミング学習を開始し現在も挫折せずに趣味で学習を楽しんでいる51歳。プログラミングの楽しさをブログを通してお伝えしていきます。

もりぴをフォローする

コンストラクタのパターンを実装する

今回ご紹介するコンストラクタのプログラムのコードは、あくまでも参考例です。

参考例を元にして、もっとあなたらしいコードを書くヒントになれば良いと思っております。

通常の構造体の初期化

まずは、通常の構造体の初期化パターンを見てみましょう。

// 通常の構造体の初期化
package main

import "fmt"

type User struct {
    Name    string
    Age     int
    Address string
}

func main() {
    user1 := User{
	Name:    "もりぴ",
	Age:     51,
	Address: "青森県",
    }

    user2 := User{
	Name: "ひろし",
	Age:  28,
    }

    fmt.Println(user1)
    fmt.Println(user2)
}
// 出力結果
$ go run main.go
{もりぴ 51 青森県}
{ひろし 28 }

一般的な構造体の初期化です。

もりぴ
もりぴ

この記述が一般的なのですが、ちょっとした問題点もあります。

一般的な構造体の初期化の問題点
  • 構造体を初期化が多くなればなるほど、プログラムのコードが長くなる
  • 構造体のデータの漏れが出てくる

上記のプログラム例だと user2 に住所の部分が空白文字として登録されています。

全て必須項目であれば、これは問題になりかねません。

そこで、登場するのがコンストラクタパターンの実装です。

コンストラクタのパターンを実装する例(参照渡し)

上記のプログラムを参考に関数を定義してみます。

コンストラクタパターンは参照渡しが一般的です。

// コンストラクタのパターンを実装
package main

import "fmt"

type User struct {
    Name    string
    Age     int
    Address string
}

// コンストラクタのパターン
func New(name string, age int, address string) *User {
	return &User{Name: name, Age: age, Address: address}
}

func main() {
    user1 := New("もりぴ", 51, "青森県")
    user2 := New("ひろし", 28, "北海道")

    fmt.Println(user1)
    fmt.Println(user2)

    // 実体を出力する
    fmt.Println(*user1)
    fmt.Println(*user2)
}
// 出力結果
$ go run main.go
&{もりぴ 51 青森県}  // ポインタ
&{ひろし 28 北海道}
{もりぴ 51 青森県}  // 実体
{ひろし 28 北海道}

このコンストラクタのパターンで構造体を初期化すると、ユーザー数が増えてもコードの行数も縮小できます。

さらに、関数の引数で渡すので構造体に渡す値の漏れを防ぐことができます。

ただ、関数の引数として値を渡すので、値の順番と型を把握しておかなければいけません。

【参考】コンストラクタのパターンを値渡しで実装

もちろん、関数ですから値渡しで実装するプログラムも可能になります。

// コンストラクタのパターンを実装(値渡し)
package main

import "fmt"

type User struct {
    Name    string
    Age     int
    Address string
}

// コンストラクタのパターン(ポインタ)
func New(name string, age int, address string) User {
	return User{Name: name, Age: age, Address: address}
}

func main() {
    user1 := New("もりぴ", 51, "青森県")
    user2 := New("ひろし", 28, "北海道")

    fmt.Println(user1)
    fmt.Println(user2)
}
// 出力結果
$ go run main.go
{もりぴ 51 青森県}
{ひろし 28 北海道}

【最後に】構造体の初期化を楽にするコンストラクタパターン

今回は「構造体の初期化を楽にするコンストラクタパターン」をお伝えしていきました。

構造体の初期化以外でもコンストラクタのパターンは多く見かけます。

プログラムの可読性を高めるためにも、このようなパターンを多く知っておくことが大切です。

これから、Go言語のプログラムに見る際に参考になると思いますので身につけておきましょう。

comment

タイトルとURLをコピーしました