Golang開発のメモ
Goインストール
最新リリースをダウンロードします。
wget https://go.dev/dl/go1.22.5.linux-amd64.tar.gz
既存のGoを削除して、新しいGoを解凍します。
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.22.5.linux-amd64.tar.gz
パスの設定を.bashrcに追加します。
GOLANG_PATH="/usr/local/go/bin"
export PATH="$PATH:$GOLANG_PATH"
export GOPATH="$HOME/go"
export PATH="$PATH:$GOPATH/bin"
インストールが完了したら、バージョンを確認します。
go version
以下のように表示されれば、インストールは完了です。
go version go1.22.5 linux/amd64
参考にしたページ
Goプロジェクトの作成
プロジェクトディレクトリを作成します。
mkdir -p $GOPATH/github.com/naughty-ghost/hello
プロジェクトディレクトリに移動します。
cd $GOPATH/github.com/naughty-ghost/hello
main.goファイルを作成します。
touch main.go
main.goファイルに以下のコードを記述します。
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
main.goファイルをビルドします。
go build
実行ファイルが生成されます。
./hello
以下のように表示されれば、プロジェクトの作成は完了です。
Hello, World!
Go モジュール
Goモジュールを初期化します。
go mod init github.com/naughty-ghost/hello
hogeモジュールを追加する場合は、以下のようになります。
go install github.com/naughty-ghost/hoge
go.modの未使用のGo モジュールを削除する、かつコード上で使用されているがgo.modに追加されていないGo モジュールを追加します。
go mod tidy
Go テスト
テストファイルを作成します。
touch main_test.go
main_test.goファイルに以下のコードを記述します。
package main
import "testing"
func TestHello(t *testing.T) {
got := Hello()
want := "Hello, World!"
if got != want {
t.Errorf("got %q want %q", got, want)
}
}
テストを実行します。
go test
以下のように表示されれば、テストは成功です。
ok github.com/naughty-ghost/hello 0.001s
命名規則
Go言語の命名規則は以下の通りです。
- ファイル名: スネークケース。(例)hello_world.go
- ディレクトリ名: 小文字。1単語が望ましい。複数の単語がある場合はケバブケース。
- パッケージ名: 小文字。1単語が望ましい。複数の単語がある場合はスネークケース。(例)http time など。
- 関数名: 外部に公開する場合は戦闘を大文字にするというGo言語のルールがあるのでそれに合わせて、アッパーキャメルケースかローワーキャメルケースを使い分ける。
- 構造体名: 外部に公開する場合は戦闘を大文字にするというGo言語のルールがあるのでそれに合わせて、アッパーキャメルケースかローワーキャメルケースを使い分ける。
- 変数名: 短い変数名が推奨されますが、変数のスコープが広い場合は長い変数名を使うこともあります。変数名はローワーキャメルケースを使います。
参考にしたページ
Go + Docker でマルチステージビルドを使用する
マルチステージビルドを使用すると、ビルド時に必要なファイルをコピーするだけで、 実行時には不要なファイルを含めないことができる。 以下のように、マルチステージビルドを使用する。
FROM golang:1.22 AS build
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o app main.go
FROM alpine
COPY --from=build /app/app /app/
WORKDIR /app
CMD ["./app"]
Go + Docker でscratchイメージを使用するときの注意
cgoを無効化する
cgoが有効なままビルドすると、scratchイメージで実行できない。 ビルド時にcgoを無効化するためには、CGO_ENABLED=0を環境変数に設定する。
CGO_ENABLED=0 go build -o app main.go
ルートCA証明書をコピーする
ルートCA証明書をコピーしないと、Dockerイメージ内でSSL通信ができない。 ルートCA証明書を別のイメージから コピーすることができる。今回は、golang:1.22の/etc/ssl/certs/ca-certificates.crtを使用する。 Dockerfileに以下を追加する。
FROM golang:1.22 AS build
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o app main.go
FROM scratch
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ # 証明書のコピー
COPY --from=build /app/app /app/
WORKDIR /app
CMD ["./app"]
scratchイメージのタイムゾーンを設定する
scratchイメージにはタイムゾーンが設定されていない。 以下のように、タイムゾーンを設定する。
FROM scratch
COPY --from=golang:1.22 /usr/share/zoneinfo /usr/share/zoneinfo
ENV TZ=Asia/Tokyo
もしくはソースコードのmainパッケージでtime/tzdataをインポートする。
import _ "time/tzdata"
Dockerイメージのサイズを小さくする
scratchイメージを使用すると、Dockerイメージのサイズを小さくすることができる。 以下のように、scratchをベースイメージに指定する。
FROM scratch
Go + PostgreSQL
id に自動生成のUUIDを設定する
"github.com/gofrs/uuid"
"gorm.io/driver/postgres"
"gorm.io/gorm"
パッケージを使用して、idに自動生成のUUIDを設定する。
Id uuid.UUID `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()"`
マイグレーション時にuuid_generate_v4が存在しないエラーが発生したら次のSQLを実行する。
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
更新履歴
- 新規作成。
- 更新。