0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Go入門 #01:宣言か代入か?:= / = / var まとめ

Posted at

変数宣言と代入の基本

宣言後の値の更新は常に =:=/var は宣言専用。

記法 目的 右辺は必須か 使える場所 初期化の挙動 同一スコープでの再宣言
:= 新規宣言+初期化 必須 関数内のみ 右辺の値で必ず初期化 不可(※複数代入で新規が1つ以上あれば文としてはOK)
= 代入のみ 必須 どこでも(宣言済みに限る) —(宣言しないので該当なし) —(宣言しないので該当なし)
var 宣言(+任意で初期化) 任意 どこでも 右辺なし→ゼロ値/右辺あり→その値で初期化 不可
  • ゼロ値
    • 変数を初期化式なしで宣言したときに自動で入る既定値。型ごとに決まっています
  • 初期化
    • 宣言時に値をセットする行為全般で、ゼロ値でのセットも“初期化”に含まれます

コード例

// var: 宣言(右辺なしならゼロ値)
var x int // 0

// :=: 新規宣言+初期化(関数内)
y := 10

// =: 宣言済みに代入
y = 20

避けたい書き方(再代入と新規が入り混じっているため)

a := 1
b := 2

a := 3       // NG: 新規が1つも無いので再宣言不可
a, b := 3, 4 // NG: 新規が1つも無いので再宣言不可
a, c := 5, 6 // OK: aは代入、cは新規(少なくとも1つ新規)

シャドーイングの落とし穴

シャドーイング:外側と同名の新しい変数を内側で宣言して、外側を隠すこと

避けるべき理由

  • バグの温床
  • エラー処理の取りこぼし
  • 可読性、レビュー性の低下
package main

import "fmt"

func main() {
    x := 10
    if true {
        x := x + 10
        fmt.Println("x:", x) // 20 になる
    }
    fmt.Println("x:", x)    // 10 のまま
}

典型バグ1:if の初期化子で外の変数を“更新したつもり”

f, err := os.Open("in.txt")
if err != nil { return err }

// ここ、f を更新したつもりが…
if f, err := os.Open("out.txt"); err != nil { // ← 新しい f, err を宣言(内側だけ有効)
    return err
}
defer f.Close() // ← 外側の f を close。内側の f は既にスコープ外

避け方

  • 外で必要な変数は外で宣言してから = で代入する。
var (
    f  *os.File
    err error
)
f, err = os.Open("out.txt") // ← 再代入
if err != nil { return err }
defer f.Close()

典型バグ2:if err := ...; err != nil の“err シャドー”

err := doA()
if err != nil { return err }

// ここで別の err を作る
if err := doB(); err != nil { // ← 内側専用の err
    return err
}
// ここに戻ると外側の err に戻る(doB の結果は残らない)

避け方

  • 一貫して同じ err を再利用する(= で代入)
  • もしくは名前を分ける(berr など)。静的解析ツールでも検出しやすい
if err = doB(); err != nil { return err }

典型バグ3:ビルトインをシャドー(len, new など)

len := 10        // 以後、len(...) が呼べない
_ = len

指針:組み込み名は変数名に使わない。(type, string, error, nil も避ける)

まとめ

新規は :=、更新は =、グローバルやゼロ値・型明示は var、そして内側で同名を作らない(シャドー禁止)——これだけ守れば宣言・代入・スコープ起因の事故はほぼ防ぐことができます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?