golang備忘録
go run <ファイル名>
で実行
Goでは、最初の文字が大文字で始まる名前は、外部のパッケージから参照できるエクスポート(公開)された名前( exported name )です。 例えば、 Pi は math パッケージでエクスポートされています。
小文字ではじまる pi や hoge などはエクスポートされていない名前です。
パッケージをインポートすると、そのパッケージがエクスポートしている名前を参照することができます。 エクスポートされていない名前(小文字ではじまる名前)は、外部のパッケージからアクセスすることはできません。
関数の最初で返り値に名前をつけることができる。これをnaked returnという
package main
import "fmt"
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
func main() {
fmt.Println(split(17))
}
PythonとGolangの対応(by ChatGPT)
- パッケージとモジュール管理
Python: pipとrequirements.txtまたはPipfile、Poetryなどで依存関係を管理。
Go: go modを用いてgo.modとgo.sumファイルで依存関係を管理。
対応: Pythonの仮想環境はGoでは不要です。go.modがその役割を果たします。 - エントリーポイント
Python: 特定のスクリプトファイルまたは__main__.py。
Go: mainパッケージとその中のmain()関数。
対応: if name == "main":のブロックに相当します。 - ディレクトリ構造
Python: 通常、src, tests, setup.pyなど。
Go: cmd, pkg, internal, apiなどのディレクトリでよく整理されます。
対応: Pythonの__init__.pyが不要で、ディレクトリ名自体がパッケージ名になります。 - 公開と非公開
Python: _で始まる名前は非公開とされる。
Go: 大文字で始まる名前が公開、小文字で始まる名前が非公開。
対応: Pythonの_variableはGoではvariable、Variableは公開されます。 - エラーハンドリング
Python: tryとexceptを使用。
Go: if err != nilを頻繁に使用。
対応: Pythonの例外機構に相当するものはGoには存在しません。 - 同時実行
Python: threadingやasyncio。
Go: ゴルーチン(Goroutines)とチャネル(Channels)。
対応: GoのゴルーチンはPythonのスレッドよりも軽量です。 - 型システム
Python: 動的型付け。
Go: 静的型付けですが、型推論がある。
対応: Pythonの型ヒントに近いが、Goはコンパイル時に厳格です。 - テスト
Python: unittestやpytestなど。
Go: 組み込みのtestingパッケージを使用。
対応: pytestのフィクスチャなどはGoにはありませんが、テーブル駆動テストが一般的です。 - Webフレームワーク
Python: Django, Flaskなど。
Go: Gin, Echo, Revelなど。
対応: FlaskのようなマイクロフレームワークにはGinが、Djangoに近いものにはRevelがあります。 - コミュニティとライブラリ
Python: 科学計算、データ分析、Web開発など多岐にわたる。
Go: システムプログラミング、Webサーバ、ネットワークツールなどに特化。
対応: GoはPythonよりもパフォーマンスが要求される分野でよく使われます。
このように、GoとPythonは多くの類似点がありつつも、それぞれが独自の哲学と設計思想を持っています。Goは特に並行処理や静的コンパイル、シンプルな言語仕様などで優れています。それぞれの特徴を理解することで、より効率的にGoを学んでいくことができるでしょう。
go.modはpipfile、go.sumがpipfile.lockみたいなもん
Golangのプログラムの実行とファイルの読み込みに関する特徴
-
モジュールの読み込み: go.modに記載された依存関係に基づいて、モジュールが読み込まれます。go buildまたはgo runを実行すると、必要な依存関係が自動的にダウンロードされます。
-
コンパイルと実行: Goはコンパイル型言語です。ソースコードは実行可能バイナリにコンパイルされ、そのバイナリを実行します。Pythonのようにインタプリタが必要ないため、デプロイが簡単です。
-
パッケージとスコープ: Goのプログラムは、packageキーワードで名前空間(パッケージ)を定義します。大文字で始まる変数や関数は外部からアクセス可能(公開)、小文字で始まるものはパッケージ内からのみアクセス可能(非公開)です。
-
エントリーポイント: mainパッケージとその中のmain()関数がプログラムのエントリーポイントです。この構造が必要です。
-
自動フォーマット: go fmtコマンドにより、ソースコードが自動的に整形されます。これによって、コードスタイルの一貫性が保たれます。
-
標準ライブラリ: Goの標準ライブラリは非常に充実しており、ネットワークプログラミング、データ処理、暗号化など多くのタスクを網羅しています。
-
テストの統合: go testコマンドで、組み込みのテスティングフレームワークを用いてテストを実行できます。
-
エラーハンドリング: Goは、戻り値としてエラーを返す独特のエラーハンドリングメカニズムを持っています。これは、例外処理が存在しないための仕組みです。
-
並行処理: Goは、ゴルーチンとチャネルを用いて簡潔かつ効率的な並行処理を実現します。
-
クロスコンパイル: Goはクロスコンパイルが容易で、1つのOSで別のOS向けのバイナリを生成することができます。
モジュール管理の開始コマンドは以下
go mod init <moduleName>
<moduleName>には大抵githubのリンクを使用する
Swaggo設定項目一覧(by ChatGPT)
swaggo/swag には、Goのコードのコメントとしてドキュメントを追加するための多くの注釈(アノテーション)が用意されています。以下は、主要なアノテーションとその説明を示す一覧です:
@swaggo:
API全体の情報を定義します。main.go またはメイン関数の近くに配置することが一般的です。
@tags:
エンドポイントのカテゴリやグループを定義します。
@summary:
エンドポイントの簡単な説明を提供します。
@description:
エンドポイントの詳細な説明を提供します。
@accept:
エンドポイントが受け入れることができるリクエストのMIMEタイプを指定します。
@produce:
エンドポイントが生成するレスポンスのMIMEタイプを指定します。
@param:
エンドポイントに渡されるパラメータを定義します。
@success および @failure:
成功時と失敗時のレスポンスを定義します。
以下は、これらのアノテーションを使用したサンプルエンドポイントのコメントです:
// @tags Users
// @summary Retrieve user by ID
// @description Retrieve detailed information about the user specified by ID
// @accept json
// @produce json
// @param id path int true "User ID"
// @success 200 {object} UserResponse "Successfully retrieved user"
// @failure 400 {object} ErrorResponse "Invalid request"
// @failure 404 {object} ErrorResponse "User not found"
// @router /users/{id} [get]
func GetUserByID(c *gin.Context) {
// ... implementation ...
}
type UserResponse struct {
ID int `json:"id"`
Name string `json:"name"`
}
type ErrorResponse struct {
Message string `json:"message"`
}
このサンプルでは、/users/{id} エンドポイントを定義しています。このエンドポイントは、指定されたIDのユーザーの情報を取得します。コメントには、エンドポイントのタグ、概要、説明、受け入れるリクエストのタイプ、生成するレスポンスのタイプ、パラメータ、および成功時と失敗時のレスポンスを定義しています。
このようなコメントをコードに追加することで、swag init コマンドを実行すると、Swaggerのドキュメントが自動的に生成されます。
goのモジュールのキャッシュ削除
go clean --modcache
Ginにおけるディレクトリ構成の最適解(by ChatGPT)
Ginや他のGoのWebフレームワークにおけるディレクトリ構成の「最適解」は、プロジェクトの要件やチームの好みによって異なることがあります。ただし、一般的なベストプラクティスや推奨されるディレクトリ構成を以下に示します:
/myapp
├── cmd/
│ └── server/
│ └── main.go # アプリケーションのエントリーポイント
├── api/
│ ├── routes.go # ルーティングの定義
│ └── middlewares.go # ミドルウェアの定義
├── controllers/
│ ├── user.go
│ └── post.go
├── models/
│ ├── user.go
│ └── post.go
├── services/
│ ├── user_service.go
│ └── post_service.go
├── repository/
│ ├── user_repo.go
│ └── post_repo.go
├── config/
│ └── config.go # 設定関連(環境変数、設定ファイルなど)
├── database/
│ └── db.go # データベース接続と初期化
├── utils/ # ヘルパー関数やユーティリティ
├── tests/ # テスト関連のファイル
└── go.mod & go.sum # Goのモジュール関連のファイル
- cmd/: アプリケーションのエントリーポイントを含むディレクトリ。
- api/: ルートやミドルウェアの定義を含む。
- controllers/: 各エンドポイントのハンドラ関数を含む。
- models/: データベースのモデルや構造体を定義する。
- services/: ビジネスロジックを含む。コントローラーとリポジトリの間で動作する。
- repository/: データベースへのアクセスや操作を行う関数を含む。
- config/: アプリケーションの設定を管理する。
- database/: データベース接続や初期化関連のコードを含む。
- utils/: 共通のヘルパー関数やユーティリティを含む。
- tests/: テスト関連のファイルやモックを含む。
この構成は、モジュール性と拡張性を考慮して設計されています。しかし、プロジェクトの規模や要件によっては、上記の構成を調整する必要があるかもしれません。最終的には、チームが最も効率的に作業できる構成を選択することが重要です。
@Paramアノテーションの概要
trueは、そのパラメータが必須(必須入力)であることを示しています。
@Paramアノテーションの構造は以下のようになります:
// @Param [name] [type] [data type] [description] [required]
- name: パラメータの名前
- type: パラメータが存在する場所(例:path, query, body, headerなど)
- data type: パラメータのデータ型(例:string, int, []stringなど)
- description: パラメータの説明
- required: そのパラメータが必須かどうか。trueは必須、falseはオプションを示します。
例えば、以下の@Paramアノテーション:
// @Param logs body []schemas.Log true "ログデータ"
このアノテーションは、リクエストボディとしてlogsという名前のパラメータを期待しており、そのデータ型は[]schemas.Log(Log構造体の配列)であり、このパラメータは必須であることを示しています。また、"ログデータ"という説明も付与されています。
exeのバージョニング
Goのプログラムにバージョン情報を埋め込む一般的な方法は、ビルド時に-ldflagsを使用して変数をセットすることです。
例えば、プログラム内で以下のような変数を持っているとします:
package main
var version = "dev"
func main() {
fmt.Println("Version:", version)
}
このversion変数をセットするために、ビルド時に以下のようにします:
go build -ldflags "-X main.version=1.0.0" -o myapp.exe
goでsqlite3を使うのに必要なもの
cgoとgccについて説明いたします。
cgo:
cgoはGoプログラム内でCコードを呼び出すためのインターフェイスです。
Goの標準ライブラリの一部として提供されています。
cgoを使用すると、Goから直接Cライブラリや関数を呼び出すことができます。これにより、Goが直接サポートしていないネイティブライブラリの機能をGoプログラム内で使用することができます。
ただし、cgoを使用することで、Goの静的コンパイルの利点が一部失われる可能性があります。また、CとGoの間でのデータのやり取りやメモリ管理に注意が必要です。
gcc:
gcc(GNU Compiler Collection)は、C、C++、Fortranなどのプログラミング言語用のコンパイラのコレクションです。
元々はC言語のためのコンパイラとして開発されましたが、現在では多くの言語をサポートしています。
gccはオープンソースであり、さまざまなプラットフォームで使用されています。
cgoを使用してGoプログラムをコンパイルする場合、Cコードの部分をコンパイルするためにgccが必要となります。
要するに、cgoを使ってGoでCコードを呼び出す場合、そのCコードをコンパイルするためのツールとしてgccが必要になります。これがgo-sqlite3のような一部のGoパッケージでgccが必要とされる理由です。
不要なモジュールの消し方
go mod tidy
GORMでのテーブル名のルール
GORM(GoのORMライブラリ)のデフォルトの動作では、テーブル名は構造体の名前を複数形のスネークケース(小文字のアンダースコア形式)に変換したものになります。
例えば、あなたの提供したコードにおいて:
Log 構造体のテーブル名は logs
Traceback 構造体のテーブル名は tracebacks
となります。
もしテーブル名をカスタマイズしたい場合は、構造体に TableName メソッドを実装することで変更することができます。例えば、Log 構造体のテーブル名を system_logs にしたい場合は、以下のようにします:
Copy code
func (Log) TableName() string {
return "system_logs"
}
これにより、Log 構造体は system_logs テーブルにマッピングされます。
リストの定義方法
var schemaLogs []schemas.LogResponse と schemaLogs := make([]schemas.LogResponse, 0) の違いは、初期化の方法と、その結果のスライスの状態にあります。
var schemaLogs []schemas.LogResponse
これは、schemaLogs を nil スライスとして宣言しています。
初期状態では、schemaLogs の値は nil です。
len(schemaLogs) は 0 ですが、schemaLogs == nil は true となります。
JSONにシリアライズすると、null となります。
schemaLogs := make([]schemas.LogResponse, 0)
これは、長さ0の空のスライスを作成して、それを schemaLogs に代入しています。
初期状態では、schemaLogs の値は空のスライス ([]) です。
len(schemaLogs) は 0 ですが、schemaLogs == nil は false となります。
JSONにシリアライズすると、[](空の配列)となります。
要するに、最初の方法ではスライスはnilとして初期化され、JSONに変換するとnullになります。一方、2つ目の方法ではスライスは空(但しnilではない)として初期化され、JSONに変換すると空の配列[]となります。
godoc
godocはGoのソースコードに書かれたコメントを元にドキュメンテーションを生成します。以下はgodocの基本的なコメントの書き方と、さまざまなコメントの書き方を示しています:
- 基本的な書き方
パッケージのコメントは、そのパッケージの直前に書きます。
Copy code
// Package mypkg はmypkgに関する機能を提供します。
package mypkg
関数、変数、定数、型に対するコメントは、その名前で始めます。
Copy code
// Add は二つの整数を加算します。
func Add(a, b int) int {
return a + b
}
- セクションの分割
コメント内で空行を使用することでセクションを分割することができます。
Copy code
// ParseValue は文字列を解析して整数を返します。
//
// 使用例:
// val, err := ParseValue("42")
- インラインコード
バッククォート(`)を使用してインラインコードを書くことができます。
Copy code
// `ParseValue`関数は文字列を整数に変換します。
-
マークアップ
特定のマークアップはサポートされていませんが、一般的なテキストの整形が利用できます。 -
インデント
コメント内でインデントを使用すると、プリフォーマットされたテキストとして表示されます。
Copy code
// Config は設定情報を表します。
// 以下は使用例です:
// config := &Config{
// Port: 8080,
// Host: "localhost",
// }
- URL
コメント内のURLは自動的にリンクとして生成されます。
Copy code
// 詳細は https://example.com を参照してください。
- 関連項目の参照
他の関数やメソッド、変数などを参照する場合、その名前をコメント内に書くことで自動的にリンクされます。
Copy code
// See also: OtherFunction
これはgodocの基本的なコメントの書き方とそのバリエーションを示したものです。公式なドキュメントや他のGoのプロジェクトを参照することで、さらに多くの書き方や実践的な例を見ることができます。
wireを使ったサーバーの起動
go run main.go wire_gen.go
クロスコンパイル
環境変数で指定する
-
GOOS
: コンパイル対象OS (windows, darwin, linux) -
GOARCH
: コンパイル対象アーキテクチャ (amd64, arm)
WindowsOSへのコンパイル
set GOOS=windows
set GOARCH=amd64
go build -o myapp-windows-amd64.exe
MacOSへのコンパイル
set GOOS=darwin
set GOARCH=amd64
go build -o myapp-macos-amd64
LinuxOSへのコンパイル
set GOOS=linux
set GOARCH=amd64
go build -o myapp-linux-amd64