Go言語
作成日時:2024-08-27
更新日時:2024-08-27
go-swagger/go-swagger: Swagger 2.0 implementation for go
connectrpc/connect-go: The Go implementation of Connect: Protobuf RPC that works.
sqlc-dev/sqlc: Generate type-safe code from SQL
インストール
Download and install - The Go Programming Language
GOPATH set to GOROOT “ディレクトリ” has no effect
GOPATHがGOROOTと同じディレクトリに設定されている場合に発生する警告。
GOPATH: Go言語のワークスペースのルートディレクトリ
GOROOT: Go言語のインストールディレクトリ
環境変数を正しく設定する。
フロー
# モジュール作成
go mod init モジュール名
# ソース解析。ライブラリDLや不要ファイル削除
go mod tidy
# ビルド
go build
リンタとフォーマッタ
VS Codeの拡張機能で十分。
CI/CDとかのチェック時に使う感じか。
リンタはgolangci-lintがよさげか。
色々なリンタを同時に実行でき、設定できる。
golangci-lintの使用方法を学ぶ|golangci-lintを理解する
# フォーマッタ:インストールと実行
go install golang.org/x/tools/cmd/goimports@latest
goimports -l -w .
# リンタインストール
go install honnef.co/go/tools/cmd/staticcheck@latest
staticcheck
go vet
サーバーメモ
Client→Proxy(nginx/Apache)→Go(Gin)
基本的にApacheからCGIで呼ぶとかは一般的では無いらしい?
(あるにはあるらしい)
APサーバーはgolangのフレームワークのプロセス単体で動く感じ。
さくらレンタルサーバー上で動かすのは無理っぽい。
(技術的には可能だけど規約的に。プロセス常時動かすのはアカン)
メモ
- 型が違うならば比較不可能
- int64 == int32 も駄目
- 基本はパスカル
チートシート
// リテラル
n = 1
n = 1_234
n = 0b110 // 2進
n = 0o567 // 8進
n = 0567 // 8進
n = 0xFF // 16進
f = 3.14
f = 1.5e20
// runeリテラル
c = 'a'
c = '\141' // 8進
c = '\x61' // 16進
c = '\u0061'// 16bit16進
c = '\U00000061' // 32bit16進
s = "a"
s = 'a'
s = `"`
// 型
// 論理型
var b bool
// 整数型
var i [u]int(8/16/32/64) // 数字が無い場合、CPUにより32か64bit。基本数字なし。
var i byte // = uint8
var c rune // = int32
// 浮動小数点数型
var f float(32|64)
1 / 0 // +Inf
0 / 0 // NaN
// 複素数型は省略
// 宣言
// ゼロ値:初期値を代入しなければ、
// 数値型は0
// 文字列は空文字
// 配列はその型のゼロ値
// スライスはnil
var i int = 1
var i = 1
var i int
var i, b int = 1, 2
var i := 1 // 関数内のみ
var (
a = 1
b int
c, d int
)
// 定数
// だいたい変数と同じ
// 型を指定しないと色々な型の変数に代入可能になったりする
const a int = 10
// 配列
var a [2]int // それぞれにゼロ値が格納
var a = [2]int{1, 2} // [1 2]
var a = [...]int{1, 2} // [1 2]
var a = [...]int{1, 6: 2} // [1 0 0 0 0 0 2]
a[0] = 1
var a [6][5]int // 長さ5の配列型が6個ある配列
// スライス
// Listみたいな感じ。あらかじめメモリを確保している。
// 足りなくなったら拡大
// なのでJavaと同じように、サイズが予測できるならばキャパシティを指定する。
// 定義
var a []int // nil
var a []int{} // 空のスライス
var a = make([]int, 3) // 長さとキャパシティが3のスライスを作成。ゼロ値が格納されている。
var a = make([]int, 0, 3) // 長さ0、キャパシティが3のスライスを作成。appendするとa[0]に追加される。
// 要素数
len(a)
// キャパシティサイズ
cap(a)
// 追加
//
a = append(a, 10)
a = append(a, 1, 2, 3)
a = append(a, anotherSlice...)
// スライスをスライス
x = x[:3] // 要素番号3"より前"をスライス
x = x[1:] // 要素番号1"以降"をスライス
// フルスライス式
// スライスからスライスするとキャパシティを共有してデータを破壊しかねない
// 3つめの数字は利用できる親スライスのキャパシティの最後の位置
// つまりサブスライスからすれば、キャパシティがフルの状態
// そこでappendをすると新しいスライスが作られる
y = x[1:2:2]
// 配列⇒スライス
x := [...]int{1, 2, 3}
s := x[:]
s := x[1:]
// メモリを共有しない安全なコピー
x := []int{1, 2, 3}
y := make([]int, len(x))
num := copy(y, x) // 戻り値はコピー数
y := make([]int, 2) // これだと1,2だけコピー。はみ出た分はコピーされない
// copyはスライスの上書きもできる
copy(x[2:], x[3:])
t := make([]int, 0, 3) // 1
s := append(t, 2) // 2
t = append(t, 3) // 3
fmt.Println(t, s) // 4:[3] [3]
// tとsは同じ基底配列を共有しているが、保持している情報(要素数)が異なった
// tにappendした段階で、tの要素数は0。そのため、appendするとs[0]を上書きした。
// 文字列⇒byte,rune変換
string(b)
[]byte(str)
[]rune(str)
// Map
var m = map[string]int // nil。書き込むとパニック
var m = map[string]int{} // マップリテラル
var m = map[string]int{
"a" : 1,
"b" : 2,
}
var m = make(map[string]int, 10)
// CRUD
m["a"] = 1
m["a"]++
delete(m, "a")
// 存在しなくてもvにはゼロ値が設定される
// なのでカンマokイディオムを使用する。
// 存在しなければokにfalseが入る
v, ok = m["a"]
// 構造体
type name struct {
a int
b string
}
c := name {
a: 1,
b: "2",
}
fmt.Println(c.a)
// 無名構造体1
var s struct {
a int
}
s.a = 1
// 無名構造体2
s := struct {
a int
}{
a: 1,
}