環境
- Windows 10
- golang1.18
- VSCode
- Docker

masayan
以下のドキュメントは一読されることをおすすめします。
https://go.dev/doc/effective_go
本シリーズの記事で説明する内容
- きほんのき
- ファイル、クラス等の命名規則や慣習
- 環境構築
- モジュールのimport
- 変数定義と代入
- ポインタ
- 配列・スライス
- マップ
- 繰り返し
- 条件分岐
- 関数
- ジェネリクス
- クラスの作り方(正確にはクラスではない)
- インターフェース
- 単体テスト
- フォーマット
- その他Tips

masayan
本記事(part1)では、上記の1~4について説明します
きほんのき
- Go言語はPHPなどのインタプリタ言語とは違い、コンパイル言語
- プログラムの実行方法
- 主にコンパイル方式をとるが、インタプリタ方式で実行することも可能
- インタプリタ方式
go run main.go
- コンパイル方式
go build main.go
でコンパイルして、./main
でバイナリを実行
- インタプリタ方式
- 主にコンパイル方式をとるが、インタプリタ方式で実行することも可能

masayan
Go言語はオブジェクト指向言語か?という論争については
クラスが用意されていない等の理由により、オブジェクト指向言語ではない、という意見もあれば、そうでないという意見もあるようです。
ファイル、クラス等の命名規則や慣習
全般
- 複数単語から成る名前をつけるときはアンダースコアを使用せず、MixedCapsまたはmixedCapsのように単語の先頭だけ大文字を用いる
var customerName string = “tanaka”
ファイル名
csv_reader.go
のように、スネークケース(すべて小文字で、複数の単語をアンダースコアで
構造体(struct)
- アッパーキャメルケース(先頭大文字から始まる)かローワーキャメルケース(先頭小文字から始まる)で
- なお、Goにはクラスはないので、クラスが必要な場合は構造体で実装する必要がある
type Recipe struct {
id int
name string
}
関数
- キャメルケースを使用。エクスポートされる関数は大文字で始める必要がある点だけ注意
- アクセス修飾子はなく、先頭が大文字ならpublic、小文字ならprivateになる
package util
// スライスの要素数を返す関数です
func Count[T any](array []T) int {
return len(array)
}
定数
const
で宣言する- ドキュメントでは特に触れられてないので、特に明確なルール等はなさそう
パッケージ名
- すべて小文字1語の名前を付ける。アンダースコアやmixedCapsは不要
- シンプルに付けること。重複しそうなときは別名importを使用
package util package time
など
ゲッターセッター(メソッド)
- 例えば、nameというフィールドなら、
- ゲッター: Name()
- セッター: SetName()
- 前述の通り、エクスポートされるメソッドは大文字で始める必要がある点だけ注意。
インターフェース名
- 1つしかメソッドがないインターフェース
- 慣習によりメソッド名に加えて-er接尾辞とする
package interfaces
type CsvReader interface {
ReadAll() (record [][]string, err error)
}
- 2つ以上メソッドがあるインターフェース
- 特にルールはなし
セミコロン
- 基本不要
スコープ
- local
- if, for等のブロック内で宣言されている
- package
- 先頭小文字でif,forなどのブロック以外(ブロックの外)で宣言されている
- global
- 先頭大文字でエクスポートされている
環境構築
- 環境ごとにymlファイル、Dockerfileをいい感じに分ける必要がある気配
開発環境
- golangが動くimageを使用したDockerでコンテナを立て、fresh等のライブラリを使用してホットリロードができるように
- fresh
- ソースコードに変更があると、自動ビルドしてくれるライブラリ
- 実行する際は、プロジェクトのルートディレクトリで
fresh
を打つだけ
- fresh
本番環境
- Dockerfileのマルチステージビルドでコンパイル環境と実行環境を分ける
- マルチステージビルドとは、1つのDockerfileで
FROM
を複数使用してbuildを行うこと
- マルチステージビルドとは、1つのDockerfileで
- 本番ではビルドしたバイナリだけを使用することで、最終的な出力イメージを小さくし、パフォーマンス向上およびセキュリティホールの対策にもなる
Dockerfile
# 本番用の中間ステージ FROM golang:1.18.2-alpine3.15 as builder RUN apk update \ && apk add --no-cache git COPY sample-go-app /sample-go-app WORKDIR /sample-go-app RUN go mod download RUN go build -o /main ./cmd/main.go # 本番用ステージ FROM alpine:3.15 as prod COPY --from=builder /main . ENV PORT=${PORT} CMD ["./main"]
Dockerfile.dev
# 開発環境用ホットリロード FROM golang:1.18as dev WORKDIR /sample-go-app COPY ./sample-go-app/go.mod ./sample-go-app/go.sum ./ RUN go install github.com/pilu/fresh@latest
モジュールのimport
- 多言語でも、自作クラスのモジュールやクラスのimportがしばしばハマり要素ではあるが、Goでは、GOPATHモードとGoModulesモードがあり、現在は後者が推奨
GOPATHモード
- 標準pkg以外を全部
$GOPATH
以下のディレクトリで管理する仕様 - プロジェクトも
$GOPATH/src
配下に作成する必要があり、この制約が開発環境の構築にネックとなっていた
GoModulesモード
- 現状のデファクトスタンダード
go.mod
ファイルを使用する- GoModulesは、Go1.11から導入され始めたGoの新しいバージョン管理システム
- 標準pkg以外の全てのパッケージをモジュールとして扱い、モジュールの管理やビルドが任意のディレクトリで可能に
- import手順は以下の通り
go mod init
<モジュール名> を実行- ディレクトリに
go.mod
というファイルが作成される - 呼び出し側のファイルで、
import
<モジュール名>/<パッケージ名> で読み込む
- go.modサンプル
modulemymodule go1.18 require ( github.com/davecgh/go-spewv1.1.0// indirect github.com/golang/protobufv1.4.2// indirect ・・・割愛・・・ )
- 自作モジュールは、go.modのmodule名+go.modがあるディレクトリからの相対パスを指定することでimport可能
- 例えば、プロジェクトのルートにgo.modがあり、一つ下の改装にinterfacesというディレクトリがあり、その中のモジュール(パッケージ名:interfaces)をimportしたい場合は以下のようになる
package main import ( "mymodule/interfaces" ) func main() { file := "sample.csv" // interfaceに代入 var csv_reader interfaces.CsvReader = classes.NewCsvReaderImpl(file) records, _ := csv_reader.ReadAll() ・・・ }
外部ライブラリのインストール
go install <package>@<version>でインストール可能です。インストールすると、go.modファイルに追記されます
※go get <package>でも可能
以上です。次回partでは5.~8.までの説明を行いたいと思います