朝、シャワーを浴びて朝ごはんを食べて、9時前ぐらいに薬一式を飲む。量が多い。
ラーメンを食べて20時前ぐらいに夜のぶんを飲んだ。
とくに体調の変化ない気がする。
朝、シャワーを浴びて朝ごはんを食べて、9時前ぐらいに薬一式を飲む。量が多い。
ラーメンを食べて20時前ぐらいに夜のぶんを飲んだ。
とくに体調の変化ない気がする。
胃カメラを飲んだ結果、ピロリ菌が多いので除菌療法をやっていくことになった。1日2回、朝と夕方に数種類の薬を1週間忘れず飲み、2ヶ月ぐらい後にまた検査を受ける。
受け取った薬は以下2つ。
とりあえず日記をつけ始めたけど、目立った副作用とかイベントがないと日記に書くことがなくなって自然消滅すると思う。
golangci-lintにはModule Pluginという仕組みがあり、設定ファイルを書いてカスタムビルドすることで独自のlinterをgolangci-lintで走らせることができます。これを使って、プロジェクト固有のlinterを組み込んだgolangci-lintをビルドして、VSCodeでも使えるようにします。
だいたい おなかが空いたら golangci-lint の Module Plugin 使おう | 東京科学大学デジタル創作同好会traP に書いてある通りの設定を入れたらよいけど、プロジェクト固有のカスタムビルドを行ったgolangci-lintでlintするためには工夫が要ります。
以下のような .custom-gcl.yml ファイルを用意します。
version: v2.12.2 name: custom-gcl destination: ./tmp plugins: # 略
コツは name と destination フィールドで、プロジェクト内の tmp/custom-gcl というパスにビルドされたバイナリが出力されるように設定します。このあたりはプロジェクトごとに好きな流儀で調整してください。
プロジェクト内の tmp/custom-gcl というパスにgolangci-lintがビルドされるとします。
以下のような設定を .vscode/settings.json ファイルに追加することで、VSCode内でカスタムビルドしたgolangci-lintを使ったlintが走るようになります。
{ "go.lintTool": "golangci-lint-v2", "go.alternateTools": { "golangci-lint-v2": "${workspaceFolder}/tmp/custom-gcl" } }
コツは ${workspaceFolder} という変数を使って設定を書くことです。VSCodeの機能として、settings.jsonなどのファイル内で展開される変数を使って設定を記述できます*1。こうすることで、カスタムビルドしたgolangci-lintのバイナリをPATHが通ったディレクトリにコピーする必要がなく、プロジェクト固有のlinterを組み込んで好きに使うことができます。
表題のものを書きました。どうぞご利用ください。
go install や go tool コマンドなどで落としてきて直接使う方法です。-header オプションに必要な表記を文字列で渡して使います。-fix オプションを渡すことで自動修正できます。
% copyrightheader -header='Copyright (c) Your Name' ./...
go vet コマンド経由go vet コマンドの -vettool オプション経由で使うことができます。
% go vet -vettool=$(which copyrightheader) -copyrightheader.header='Copyright (c) Your Name' ./...
golangci-lintのModule Plugin Systemの仕組みを使うことで、カスタムlinterとして組み込んで動作させることができます。
plugins: - module: github.com/utgwkk/copyrightheader import: github.com/utgwkk/copyrightheader/plugin
設定項目はこういう感じで書けます。
linters: enable: - copyrightheader settings: custom: copyrightheader: type: module settings: header: 'Copyright (c) Your Name'
Goファイル先頭のコメントの内容を検査するlinterとしては、すでにgo-headerが存在し、golangci-lintにデフォルトで組み込まれています。また、go-headerのほうが設定項目も機能も多いので、普通にgo-headerを使ったほうがいいんじゃないか、と思われるでしょう。
go-headerにはパフォーマンスの問題があります。既にissueで報告されているように、検査するファイルごとに git コマンドを実行しているため、ファイル数が多くなるとlinterの実行時間がどんどん長くなってしまいます。著作権表記のテンプレートに年を入れない場合でも git コマンドの実行を回避することができません。
自分が関わっているプロジェクトでも、まだコードベースがそこまで大きくないのにも関わらずgo-headerの実行時間が golangci-lint run --verbose コマンドの実行ログにTop10として表示されるようになっていました。これからコードベースが育っていくにつれて、linterの実行時間が問題になることが考えられます。
年を含まない著作権・ライセンス表記が各Goファイルに入っていることを保証できればよい、という要件に絞れば実装はそこまで難しくないので、さっと作ることにしました。
例によって、Claude Codeに全てを実装してもらいました。自分でも何をやっているのか読める範囲のコードではあるけど、試行錯誤のスピードが段違いなので全て任せてしまうほうが早いですね。
go-headerと検査ルールが丸かぶりしている上に機能も足りていないので、すぐには取り込めないんじゃないかな~。自分としてはデフォルトで組み込みたいというモチベーションは今のところないです。それよりは、go-headerのパフォーマンスの問題を解決できるほうがよさそう。
Dear Kiki!
— うたがわきき@C108 日曜日 東V44b (東7ホール) (@utgwkk) 2026年7月2日
We're sorry, but the following sessions have not been accepted for Go Conference 2026:⁰- Goは関数型ドメインモデリングの夢を見るか?
Thanks,
Go Conference 2026
無念!! Go Conference 2026は個人でスポンサーしているし、万難を排して行くつもりです。中野セントラルパークカンファレンスで会いましょう。
Goでアプリケーションを開発する際、複雑なドメインロジックをどうコードに落とし込むべきか悩んだことはありませんか。また、いざドメインロジックを実装してみたものの、データストアや外部APIの都合に引きずられ、後からコードを読んでも結局何がどうなるのか理解しづらいと思った経験はありませんか。そんなあなたに「関数型ドメインモデリング」を知っていただきたいです。
「関数型ドメインモデリング」(Domain Modeling Made Functional) [1][2] は、関数型プログラミングと型システムを活用したドメイン駆動設計の手法について説明した本です。「関数型ドメインモデリング」の主要な考え方を要約すると、以下のようになります。
- ドメイン駆動設計の考え方に基づき、ドメインを理解する
- ドメインモデルを代数的データ型でモデリングする
- 一連の手続きをワークフロー (副作用を持たない状態遷移の単位) に分解し、連結させる
- ドメインロジックを純粋関数で記述し、副作用を端に追いやる
「関数型ドメインモデリング」では実装言語として F# が用いられていますが、考え方のエッセンスはプログラミング言語に依存しません。私が所属する会社では「関数型ドメインモデリング」を輪読し、チームに分かれて複数の言語で実装を移植する会が過去に開催され、Goでの移植も行いました[3]。また、筆者は実際にGo製Webアプリケーションの開発に対して、関数型ドメインモデリングの考え方を取り入れた経験があり、また別のプロジェクトでもまさに現在進行形で実践しています。
本トークでは、Goでどのようにドメインの複雑さに立ち向かうことができるのか・Goでの関数型ドメインモデリングを「夢」で終わらせないためにどのようにアレンジして取り入れたのか、についてお話しします。 以下のような話題について、簡単な (しかし自明でないドメインロジックがある) アプリケーションを例に挙げつつお話しする予定です。
- 「関数型ドメインモデリング」のおさらい
- ワークフローをGoのコードとして表現する
- Goの型・言語機能を活かしたドメインモデリング
- 永続化層での表現とドメインモデルとのギャップを吸収する
- 関数型ドメインモデリングと「Goらしい」コードとのギャップを埋め、すこやかに開発できるポイントを探求する
- どうやって依存を注入するか
errorinterfaceとResult型nilとOption型- Goの言語機能の進化と関数型ドメインモデリング
- メソッドのジェネリクス対応 [4]
本トークを通じて、複雑なドメインロジックをGoで実装する際の選択肢を増やすことにつながり、健やかなアプリケーション開発への一助となれば幸いです。
[1]: https://tatsu-zine.com/books/domain-modeling-made-functional
[2]: https://pragprog.com/titles/swdddf/domain-modeling-made-functional/
[3]: https://developer.hatenastaff.com/entry/2025/10/31/153000
[4]: https://github.com/golang/go/issues/77273
設定ファイルに以下のような記述を足したらよいです。
replacements: - tables: [] match: db_type: 'bigint' replace: 'int'
stephenafamo/bobはGoのO/Rマッパーで、DBスキーマの定義からGoのコードを生成することで型安全に扱えるという特徴を持っています。
stephenafamo/bobには、ドライバが推論した型を上書きするための設定項目があるので、これを利用して、全てのテーブルの BIGINT 型のカラムをGoの int 型に対応させるように上書きしています。
int 型は64ビットとは限らないけど大丈夫なの?Goの言語仕様をよく読むと、int 型について以下のように規定されています。
uint either 32 or 64 bits
int same size as uint
すなわち、int 型は処理系によって32ビットもしくは64ビット整数のいずれかを表しています。手元のパソコンやVM・Dockerコンテナではだいたい64ビットになっていると思います。より正確に調べるには unsafe.Sizeof(int(0)) の実行結果 (バイト数が表示される) を確認するとよいです。
一般的なWebアプリケーションの動作環境を念頭に置くと、現代で64ビットプロセッサが使えない環境をわざわざ選ぶ理由もないと思うし、まあいいんじゃないでしょうか。逆に、シビアな環境の場合は気にする意味が出てくると思います。
表題のものをリリースしました。
go install コマンドもしくは go get -tool コマンドでインストールして使うことを推奨しています。現代なので go get -tool コマンドを使うのがいいと思います。
たとえば、resolver.go というファイルに以下のようなstruct定義があったとします。各 Usecase 型はinterfaceになっており、対応する実装を何らかの方法で依存注入する必要があります。
type Resolver struct { user user.Usecase blog blog.Usecase entry entry.Usecase comment comment.Usecase }
gosimplectorgenを使って gosimplectorgen resolver.go というコマンドを実行すると、以下のような関数が resolver_gen.go というファイルに生成されます。このように、引数から受け取った値をstructのフィールドに埋めて返す関数のことをコンストラクタ関数と個人的に呼んでいます (以下、この記事内でもそのように呼びます)。
func NewResolver( user user.Usecase, blog blog.Usecase, entry entry.Usecase, comment comment.Usecase, ) *Resolver { return &Resolver{ user: user, blog: blog, entry: entry, comment: comment, } }
基本的な機能はこれだけです。
以下のコマンドライン引数でコード生成の挙動を変えられます。
-out
-targetTypes
Goでstructに対してinterfaceを経由して依存注入を行う場合、なんらかの方法でstructのフィールドをセットしていくことになると思います。よくあるのが、先述したようにコンストラクタ関数 (structのフィールドを埋めて返す関数) を定義する方法です。
コンストラクタ関数は簡単に定義できますが、以下のような課題を抱えています。
前者はたとえばexhaustruct linterで簡単に検査できますが、後者は手書きしているうちはどうしようもありません。VSCodeのGo拡張の機能を使ってstructリテラルのフィールドを自動的に埋めることで多少緩和はできますが、それでも手書きしなければならないものが残ってしまいます。
手書きするとミスの余地があるし、なんだかんだで手間な作業ではあるので、コード生成の力で自動化してしまおう、ということでツールを作りました。
サンプルコードと方針のメモ書きだけを渡してClaude Codeにだいたい実装してもらいました。本質的な実装は200行ちょっとぐらいです。
これぐらいのコードであれば、Goの静的解析を多少かじっていれば手書きできると思うけど、Claude Codeにばしばし実装してもらうほうが早いですね。OSS仕草としてREADMEやコミットメッセージなどを英語で書くようにしているけど、これもClaude Codeに文言を考えてもらったので楽でした。
golang constructor generatorで検索すると、いくつか同様のツールが出てきます。
以下の理由により、これらのツールを採用せずに自作することにしました。
ツール名にsimpleとあるように、アグレッシブな機能拡張をする予定はなく、自分にとって必要な最小限のユースケースに絞って実装しています。裏を返すと、自分が欲しいユースケースが出てきたら機能が増える可能性があります。
Goのstructのコンストラクタ関数をコード生成するツール gosimplectorgen をリリースしました。コンストラクタ関数を自動生成する、という最小限のユースケースに絞って実装したため、2時間ぐらいでだいたいできたと思います。
ユースケースに合う場合は、どうぞご利用ください。