CheatSheet
日本語 icon日本語English iconEnglish
チートシートとはカンニングペーパーのことです。それが転じて、本来覚えることをまとめておいたものです。
要点をすぐに参照できるようにまとめてみました。

Go

エンジニアのためのWebチートシート

Go(Golang)は、Googleが開発した静的型付けのコンパイル言語です。 シンプルな構文、高速なコンパイル、組み込みの並行処理(goroutine)が特徴です。 基本構文、データ型、関数、構造体、エラー処理、並行処理などをチートシートにまとめました。

基本構文

変数宣言

  • var, :=, const による変数・定数の宣言です。

    var name string = "Go"
    var age int = 15
    var isActive bool
    
    // 短縮宣言(関数内のみ)
    name := "Go"
    age := 15
    
    // 複数宣言
    var (
        host  string = "localhost"
        port  int    = 8080
    )
    const Pi = 3.14159
    const (
        StatusOK       = 200
        StatusNotFound = 404
    )

出力 & フォーマット

  • fmt パッケージによる出力とフォーマット指定子です。

    import "fmt"
    
    fmt.Println("Hello, World!")  // 改行付き出力
    fmt.Print("Hello ")           // 改行なし出力
    
    // フォーマット出力
    fmt.Printf("Name: %s\n", name)
    fmt.Printf("Age: %d\n", age)
    fmt.Printf("Pi: %.2f\n", 3.14159)
    fmt.Printf("Bool: %t\n", true)
    fmt.Printf("Type: %T\n", 42)    // int
    fmt.Printf("Value: %v\n", obj)  // デフォルト形式
    fmt.Printf("Pointer: %p\n", &x)
    
    // 文字列に格納
    s := fmt.Sprintf("Hello, %s!", name)

iota & 型変換

  • iota による連番定数と明示的な型変換です。

    type Weekday int
    const (
        Sunday Weekday = iota  // 0
        Monday                 // 1
        Tuesday                // 2
        Wednesday              // 3
    )
    
    const (
        Read    = 1 << iota  // 1 (ビットフラグ)
        Write                // 2
        Execute              // 4
    )
    // 型変換(明示的キャストが必要)
    i := 42
    f := float64(i)
    s := strconv.Itoa(i)        // int → string
    n, _ := strconv.Atoi("42")  // string → int

データ型

Goの基本データ型の一覧です。

説明
bool

true / false

string

UTF-8 文字列(イミュータブル)

int, int8, int16, int32, int64

符号付き整数

uint, uint8, uint16, uint32, uint64

符号なし整数

float32, float64

浮動小数点数

byte

uint8 のエイリアス

rune

int32 のエイリアス(Unicodeコードポイント)

complex64, complex128

複素数

文字列操作

  • 文字列リテラルと strings パッケージの主要関数です。

    s := "Hello, World!"
    s2 := `Raw string literal
    supports multiple lines`
    
    len(s)         // 13(バイト数)
    len([]rune(s)) // 文字数
    s[0:5]         // "Hello"
    import "strings"
    
    strings.Contains(s, "World")          // true
    strings.HasPrefix(s, "Hello")         // true
    strings.ToUpper(s)                    // "HELLO, WORLD!"
    strings.TrimSpace("  hi  ")          // "hi"
    strings.Split("a,b,c", ",")          // ["a","b","c"]
    strings.Join([]string{"a","b"}, ",") // "a,b"
    strings.Replace(s, "World", "Go", 1)

ポインタ

  • アドレス演算子とデリファレンスの基本です。

    x := 42
    p := &x          // *int 型(xのアドレス)
    fmt.Println(*p)  // 42(値を取得)
    *p = 100         // x も 100 に変更
    
    p2 := new(int)   // *int(ゼロ値 0)
    var p3 *int      // nil
    // 関数でポインタを使う
    func increment(n *int) {
        *n++
    }
    increment(&x)  // x が 1 増加

制御フロー

if / else

  • 条件分岐です。初期化付きifも使えます。

    if x > 0 {
        fmt.Println("positive")
    } else if x == 0 {
        fmt.Println("zero")
    } else {
        fmt.Println("negative")
    }
    // 初期化付き if
    if err := doSomething(); err != nil {
        fmt.Println("error:", err)
    }
    
    if f, err := os.Open("file.txt"); err != nil {
        log.Fatal(err)
    } else {
        defer f.Close()
    }

for ループ

  • Goの唯一のループ構文です。while相当も for で書きます。

    for i := 0; i < 10; i++ {
        fmt.Println(i)
    }
    
    n := 1
    for n < 100 { // while 相当
        n *= 2
    }
    
    for { // 無限ループ(break で脱出)
    }
    // range で反復
    for i, v := range []int{1, 2, 3} {
        fmt.Println(i, v)
    }
    for i, ch := range "Hello" {
        fmt.Printf("%d: %c\n", i, ch)
    }
    for k, v := range myMap {
        fmt.Println(k, v)
    }

switch

  • 式switchと条件なしswitchです。自動breakで fallthrough は明示的です。

    switch day { // 自動 break
    case "Mon", "Tue", "Wed", "Thu", "Fri":
        fmt.Println("Weekday")
    case "Sat", "Sun":
        fmt.Println("Weekend")
    default:
        fmt.Println("Unknown")
    }
    // 条件なし switch
    switch {
    case score >= 90:
        fmt.Println("A")
    case score >= 80:
        fmt.Println("B")
    default:
        fmt.Println("C")
    }
    // fallthrough(次のcaseも実行)
    switch n {
    case 1:
        fmt.Println("one")
        fallthrough
    case 2:
        fmt.Println("two or after one")
    }

関数

関数定義

  • 複数戻り値と名前付き戻り値をサポートします。

    func greet(name string) string {
        return "Hello, " + name
    }
    
    // 複数戻り値
    func divide(a, b float64) (float64, error) {
        if b == 0 {
            return 0, errors.New("division by zero")
        }
        return a / b, nil
    }
    // 名前付き戻り値
    func minMax(nums []int) (min, max int) {
        min, max = nums[0], nums[0]
        for _, n := range nums[1:] {
            if n < min { min = n }
            if n > max { max = n }
        }
        return
    }

可変長引数 & 無名関数

  • 可変長引数、クロージャ、即時実行関数です。

    func sum(nums ...int) int {
        total := 0
        for _, n := range nums {
            total += n
        }
        return total
    }
    sum(1, 2, 3)         // 6
    sum([]int{1,2,3}...) // スライス展開
    // 無名関数(クロージャ)
    add := func(a, b int) int { return a + b }
    fmt.Println(add(1, 2)) // 3
    
    // クロージャで状態を保持
    func counter() func() int {
        n := 0
        return func() int {
            n++
            return n
        }
    }

defer

  • 関数終了時に実行される遅延呼び出しです。LIFO順で実行されます。

    func readFile() {
        f, err := os.Open("file.txt")
        if err != nil {
            log.Fatal(err)
        }
        defer f.Close() // 関数終了時に必ず閉じる
    }
    // LIFO 順で実行
    defer fmt.Println("1st")
    defer fmt.Println("2nd")
    defer fmt.Println("3rd")
    // 出力: 3rd, 2nd, 1st
    resp, err := http.Get("https://example.com")
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
    body, _ := io.ReadAll(resp.Body)

データ構造

配列 & スライス

  • 固定長の配列と可変長のスライスです。

    var arr [3]int = [3]int{1, 2, 3} // 配列(固定長)
    arr2 := [...]int{1, 2, 3}        // 長さ自動推論
    
    s := []int{1, 2, 3}              // スライス(可変長)
    s2 := make([]int, 5)             // len=5, cap=5
    s3 := make([]int, 0, 10)         // len=0, cap=10
    s = append(s, 4, 5)           // 追加
    s = append(s, []int{6,7}...) // スライス追加
    
    sub := s[1:3]  // index 1〜2
    head := s[:3]  // 先頭3つ
    tail := s[2:]  // index 2〜末尾
    
    dst := make([]int, len(s))
    copy(dst, s)
    len(s) // 長さ cap(s) // 容量

マップ

  • キーと値のペアを持つデータ構造です。

    m := map[string]int{
        "alice": 25,
        "bob":   30,
    }
    m2 := make(map[string]int)
    
    m["charlie"] = 35  // 追加・更新
    age := m["alice"]  // 取得(25)
    delete(m, "bob")   // 削除
    // 存在確認(カンマOKイディオム)
    val, ok := m["dave"]
    if !ok {
        fmt.Println("not found")
    }
    
    for key, val := range m {
        fmt.Printf("%s: %d\n", key, val)
    }
    len(m) // 要素数

ゼロ値 & 型アサーション

  • 未初期化変数のデフォルト値と型アサーションです。

    // ゼロ値(未初期化のデフォルト値)
    // int, float → 0  bool → false  string → ""
    // pointer, slice, map, chan, func, interface → nil
    
    type UserID int64
    type Temperature float64
    // 型アサーション
    var i interface{} = "hello"
    s := i.(string)      // "hello"
    s, ok := i.(string)  // ok = true
    n, ok := i.(int)     // ok = false
    // 型スイッチ
    switch v := i.(type) {
    case string:
        fmt.Println("string:", v)
    case int:
        fmt.Println("int:", v)
    default:
        fmt.Println("unknown")
    }

構造体 & インターフェース

構造体

  • 構造体の定義、初期化、メソッドです。

    type User struct {
        Name  string
        Age   int
        Email string
    }
    
    u1 := User{"Alice", 25, "alice@example.com"}
    u2 := User{Name: "Bob", Age: 30}
    u3 := &User{Name: "Charlie"} // ポインタ
    // 値レシーバ
    func (u User) Greet() string {
        return "Hi, I'm " + u.Name
    }
    
    // ポインタレシーバ(フィールド変更可能)
    func (u *User) SetAge(age int) {
        u.Age = age
    }

埋め込み & コンポジション

  • 構造体の埋め込みによるコンポジションです。

    type Animal struct { Name string }
    func (a Animal) Speak() string {
        return a.Name + " speaks"
    }
    
    type Dog struct {
        Animal       // 埋め込み(コンポジション)
        Breed string
    }
    d := Dog{
        Animal: Animal{Name: "Pochi"},
        Breed:  "Shiba",
    }
    fmt.Println(d.Name)    // "Pochi"(昇格)
    fmt.Println(d.Speak()) // "Pochi speaks"

インターフェース

  • 暗黙的に実装されるインターフェースです。

    type Shape interface {
        Area() float64
        Perimeter() float64
    }
    
    // 暗黙的に実装(implements 不要)
    type Circle struct { Radius float64 }
    func (c Circle) Area() float64 {
        return math.Pi * c.Radius * c.Radius
    }
    func (c Circle) Perimeter() float64 {
        return 2 * math.Pi * c.Radius
    }
    func printAny(v any) { fmt.Println(v) }
    
    // Stringer インターフェース(fmt 出力用)
    func (u User) String() string {
        return fmt.Sprintf("%s (%d)", u.Name, u.Age)
    }

エラーハンドリング

基本

  • error 戻り値パターンとカスタムエラーです。

    result, err := doSomething()
    if err != nil {
        log.Fatal(err)
    }
    
    func divide(a, b float64) (float64, error) {
        if b == 0 {
            return 0, errors.New("division by zero")
        }
        return a / b, nil
    }
    // カスタムエラー型
    type ValidationError struct {
        Field   string
        Message string
    }
    func (e *ValidationError) Error() string {
        return e.Field + ": " + e.Message
    }

errors パッケージ

  • エラーのラップ、比較、型アサーションです。

    err := fmt.Errorf("open config: %w", os.ErrNotExist)
    
    if errors.Is(err, os.ErrNotExist) {
        fmt.Println("file not found")
    }
    
    var pathErr *os.PathError
    if errors.As(err, &pathErr) {
        fmt.Println("path:", pathErr.Path)
    }
    // errors.Join(Go 1.20+)
    err := errors.Join(
        errors.New("error 1"),
        errors.New("error 2"),
    )
    
    var ErrNotFound = errors.New("not found")
    var ErrTimeout  = errors.New("timeout")

panic & recover

  • パニックとリカバリーの基本です。

    func mustEnv(key string) string {
        val := os.Getenv(key)
        if val == "" {
            panic("missing env: " + key)
        }
        return val
    }
    // recover: panic をキャッチする
    func safeDiv(a, b int) (result int, err error) {
        defer func() {
            if r := recover(); r != nil {
                err = fmt.Errorf("recovered: %v", r)
            }
        }()
        return a / b, nil
    }

並行処理

goroutine

  • 軽量スレッドで並行処理を実行します。

    // goroutine: go キーワードで起動
    go func() {
        fmt.Println("Hello from goroutine")
    }()
    
    // sync.WaitGroup で完了を待つ
    var wg sync.WaitGroup
    
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(n int) {
            defer wg.Done()
            fmt.Println("Worker", n)
        }(i)
    }
    wg.Wait()  // すべての goroutine が完了するまで待つ

チャネル

  • goroutine間でデータをやり取りする仕組みです。

    ch := make(chan int)
    go func() { ch <- 42 }()
    val := <-ch // 受信(42)
    
    // バッファ付きチャネル
    ch := make(chan string, 3)
    ch <- "a"
    ch <- "b"
    ch <- "c"
    // close と range
    ch := make(chan int, 5)
    go func() {
        for i := 0; i < 5; i++ {
            ch <- i
        }
        close(ch)
    }()
    for v := range ch {
        fmt.Println(v)
    }

select & Mutex

  • 複数チャネルの待ち受けと排他制御です。

    select {
    case msg := <-ch1:
        fmt.Println("ch1:", msg)
    case msg := <-ch2:
        fmt.Println("ch2:", msg)
    case <-time.After(3 * time.Second):
        fmt.Println("timeout")
    }
    // sync.Mutex: 排他制御
    type SafeCounter struct {
        mu sync.Mutex
        v  map[string]int
    }
    func (c *SafeCounter) Inc(key string) {
        c.mu.Lock()
        defer c.mu.Unlock()
        c.v[key]++
    }

パッケージ & ツール

パッケージ & インポート

  • パッケージの宣言とインポートの方法です。

    package main   // 実行可能プログラム
    package mylib  // ライブラリ
    
    import (
        "fmt"
        "os"
        "net/http"
    )
    import (
        f "fmt"
        . "strings"   // ドットインポート(非推奨)
        _ "image/png" // 副作用のみ
    )
    
    // 大文字始まり → エクスポート
    func PublicFunc() {}
    func privateFunc() {} // パッケージ内のみ

Go コマンド

  • よく使うGoのCLIコマンドです。

    go mod init myproject          # モジュール初期化
    go mod tidy                    # 依存関係の整理
    go get github.com/pkg/errors   # パッケージ追加
    
    go run main.go     # 実行
    go build -o app .  # ビルド
    go test ./...            # 全テスト実行
    go test -v ./...         # 詳細出力
    go test -cover ./...     # カバレッジ
    go test -bench=. ./...   # ベンチマーク
    
    go fmt ./...   # フォーマット
    go vet ./...   # 静的解析