X(Twitter) Zenn GitHub RSS 共有

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のフレームワークのプロセス単体で動く感じ。

さくらレンタルサーバー上で動かすのは無理っぽい。
(技術的には可能だけど規約的に。プロセス常時動かすのはアカン)

メモ

チートシート

// リテラル
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,
}