BackEnd

GoでStructのAccessorを自動生成する

投稿日:

はじめに

DDDを採用しているとあるプロジェクトでは、structのfieldをprivateにしているため、手動で定義したGetterを介して各fieldにアクセスしています。CopilotによってGetterを生成できるとはいえ、ドメインモデルの変更に伴うfieldの変更に追従するのが面倒という課題があります。

そこで、accessorを自動生成するパッケージを使って go generate でaccessorを自動生成を試してみます。

Accessorを自動生成する

生成処理を自前で書いてもよいですが、まずはGitHubに公開されているパッケージを使って自動生成を試してみます。

今回使用するパッケージは https://github.com/masaushi/accessory です。

基本的な使い方

まず初めに、シンプルにaccessorを自動生成する方法を説明します。対象とするstructの定義は以下のとおりです。

accessorを自動生成するためには、structのfieldにaccessor tagを書く必要があります。

accessor:getter と書くと、このfieldのgetterが生成されます。同様に accessor:setter と書くと、このfieldのsetterが生成されます。

また、 getter:EmailAddress のように生成されるメソッド名を指定することもできます。

特定のfieldのaccessorを生成したくない場合は、accessor tagを書かないか、明示的に accessor:"-" と書きます。

go generate で自動生成するには、コード上に以下のように記述したうえでコマンドを実行します。

自動生成するには、typeに生成するstruct名を渡す必要があります。typeが指定されていない場合や、複数指定されている場合は生成できません。

receiver変数を変更する場合

コマンドの引数に特定のパラメータを渡すことで、自動生成の挙動をカスタマイズすることができます。

手始めに、receiver変数を指定してみます。

自動生成されたファイルでは以下のようにreceiver変数が u2 になっています。

生成するファイル名を変える場合

自動生成するファイル名を変えたい場合は、 -output で指定します。

排他制御を行い場合

accessorの排他制御を行いたい場合は、structにmutexを追加して、 -lock でfield名を指定します。

生成されたファイルは以下のとおりです。

どのように生成しているのか

DDDでの開発において、accessorのほかにも自動生成したい対象はいくつかあります。それらの自動生成を行うツールを作る参考として、このパッケージがどのようにファイルを生成しているのか、コードを見てみたいと思います。

エントリーポイント

main.go は以下のように非常にシンプルです。

cmd.Execute を実行するに当たり、引数として afero.Fsargs を渡しています。

afero.Fs は名前の通り、ファイル操作を便利にするためのパッケージのようです。

生成対象のファイルをどのように見つけているか

cmd.Execute() 関数を見てみると、以下のようになっています。

コマンドの引数に相対パスが渡されていればそのディレクトリを見に行き、渡されていなければ同一ディレクトリを見に行くようです。

structの解析

structの解析は golang.org/x/tools/go/packagespackages.Load() 関数で行っています。

その後、 *package.Packgage を自前の構造体に変換しています。

accessorを生成

accessorの生成はtemplateパッケージを使って行われます。

上記の例では、 template.TemplateParse(text string) メソッドでテンプレートファイルを読み込み、 Execute(wr io.Writer, data any) error メソッドで生成したsetterを bytes.Buffer に書き出しています。

accessorをファイル出力

ファイルへの出力では、 fmt.Fprintf()bytes.Buffer に書き込んだものを afero.WriteFile() でファイルに書き出しています。

さいごに

accessorを自動生成するパッケージの紹介と、そのパッケージがどのようにファイルを生成しているのかを調べてみました。

おすすめ書籍

初めてのGo言語 ―他言語プログラマーのためのイディオマティックGo実践ガイド Go言語 100Tips ありがちなミスを把握し、実装を最適化する impress top gearシリーズ 効率的なGo ―データ指向によるGoアプリケーションの性能最適化

blog-page_footer_336




blog-page_footer_336




-BackEnd
-

執筆者:

免責事項

このブログは、記事上部に記載のある投稿日時点の一般的な情報を提供するものであり、投資等の勧誘・法的・税務上の助言を提供するものではありません。仮想通貨の投資・損益計算は複雑であり、個々の取引状況や法律の変更によって異なる可能性があります。ブログに記載された情報は参考程度のものであり、特定の状況に基づいた行動の決定には専門家の助言を求めることをお勧めします。当ブログの情報に基づいた行動に関連して生じた損失やリスクについて、筆者は責任を負いかねます。最新の法律や税務情報を確認し、必要に応じて専門家に相談することをお勧めします。


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


関連記事

crypto

公開鍵暗号の概要、用語と使用例

1 はじめに1.1 前提条件2 暗号化と復号2.1 暗号化とは2.2 復号とは3 暗号化方式3.1 共通鍵暗号3.2 公開鍵暗号4 署名と検証4.1 署名とは4.2 検証とは5 RSA暗号とは5.1 ...

rails

Ruby、Railsの時間に関するメソッドを使用してみた

はじめに 普段PHPのお仕事をしています、tonnyです。 半年程前からRuby on Railsの勉強を始めました。 今回はよく使う時間に関するメソッドついてまとめたいと思います。 目次 1 はじめ ...

laravel logo

[Laravel] ログの扱い方 [5.8]

1 はじめに2 環境3 Monologについて4 コード上で設定する方法5 config/logging.phpで設定する方法6 おまけ:ログレベルについて7 さいごに8 おすすめ書籍 はじめに こん ...

Go言語

Go 1.19でGoDocに追加された機能

1 はじめに2 GoDocの機能追加2.1 セクションタイトル(Headings)2.2 リンク2.3 リスト2.4 パッケージの追加3 おまけ4 さいごに5 おすすめ書籍 はじめに 8月2日にGo ...

php logo

PHPでGmail APIを利用してメールデータを取得してみる

1 はじめに2 Gmail API の有効化3 OAuthクライアントの作成4 Google Clientライブラリのインストール5 OAuth認証6 メールデータの取得7 さいごに8 おすすめ書籍 ...

フォロー

blog-page_side_responsive

2024年6月
 1
2345678
9101112131415
16171819202122
23242526272829
30  

アプリ情報

私たちは無料アプリもリリースしています、ぜひご覧ください。 下記のアイコンから無料でダウンロードできます。