本文 AI 產出,尚未審核

Golang 基本語法與資料型態

單元:變數宣告與初始化(var:=


簡介

在任何程式語言中,變數都是最基礎也是最重要的概念之一。它負責在程式執行期間暫存資料,讓我們可以重複使用、計算或傳遞資訊。對於 Go(Golang)而言,變數的宣告與初始化更具備靜態型別檢查自動推斷的雙重優勢,使程式碼既安全又簡潔。

本篇文章將深入探討 Go 中兩種最常使用的變數寫法——var 關鍵字與短宣告運算子 :=。透過實作範例、常見陷阱與最佳實踐,讓讀者從「不知道怎麼宣告」一步步成長為「能在實務專案中自信使用」的開發者。


核心概念

1. var 宣告的完整語法

var 是 Go 官方提供的變數宣告方式,語法如下:

var <變數名稱> <型別> = <初始值>
  • 型別必須寫明,除非使用 零值(zero value)初始化。
  • 若省略 = <初始值>,變數會自動取得該型別的零值(例如 int0string""boolfalse)。

範例 1:基本型別宣告與零值

package main

import "fmt"

func main() {
    var i int          // i 的零值是 0
    var s string       // s 的零值是空字串 ""
    var b bool         // b 的零值是 false

    fmt.Printf("i=%d, s=%q, b=%t\n", i, s, b)
}

重點:使用 var 時,若不提供初始值,Go 會自動以零值填充,避免未初始化的記憶體讀取問題。


2. 型別推斷與多變數同時宣告

Go 允許在同一行宣告多個變數,只要型別相同或使用型別推斷即可。

var a, b, c int = 1, 2, 3          // 明確指定型別
var x, y = 3.14, "hello"          // 依照右側值自動推斷型別

範例 2:多變數同時宣告

package main

import "fmt"

func main() {
    var width, height int = 800, 600
    var pi, greeting = 3.14159, "Go 語言"

    fmt.Println("畫面尺寸:", width, "x", height)
    fmt.Println("π =", pi, "訊息:", greeting)
}

3. 短宣告運算子 :=

在函式內部(區塊作用域)最常使用 :=,語法為:

<變數名稱> := <初始值>
  • 不需要寫型別,編譯器會根據右側表達式自動推斷。
  • 必須同時 宣告初始化,不能僅宣告而不給值。
  • 若已有同名變數在外層作用域,:=重新宣告(shadow)該變數,除非在同一行同時使用已存在的變數。

範例 3:函式內的短宣告

package main

import "fmt"

func main() {
    // 使用 := 直接宣告並初始化
    counter := 0
    message := "開始計數"

    fmt.Println(message, counter)

    // 重新宣告(遮蔽)外層變數
    counter := 10 // 這裡的 counter 與上面的不同
    fmt.Println("重新宣告後的 counter =", counter)
}

注意:= 只能在函式內部使用,若在全域範圍(package level)使用會產生編譯錯誤。


4. 結合 var:= 的實務寫法

在大型專案中,常見的寫法是:

  • 全域變數:使用 var(可加上 constiota 等)以明確型別與註解。
  • 局部變數:盡可能使用 :=,讓程式碼更簡潔且型別安全。

範例 4:全域與局部變數混合

package main

import "fmt"

// 全域變數,使用 var 明確宣告
var (
    AppName string = "MyGoApp"
    Version int    = 1
)

func main() {
    // 局部變數,使用短宣告
    startTime := "2025-12-19 10:00:00"
    fmt.Printf("%s v%d 啟動於 %s\n", AppName, Version, startTime)

    // 需要重新宣告同名變數時,使用 var 明確
    var startTime = "2025-12-19 10:01:00" // 重新宣告,遮蔽上層 startTime
    fmt.Println("重新宣告後的 startTime =", startTime)
}

5. 常見型別與零值對照表

型別 零值 (Zero Value)
int 0
float64 0.0
string "" (空字串)
bool false
pointer nil
slice nil (長度 0)
map nil
channel nil
interface nil

了解零值可以避免因未初始化而產生的nil panic


常見陷阱與最佳實踐

陷阱 說明 解決方式
在全域使用 := := 只能在函式內部使用,放在檔案最上層會編譯失敗。 使用 varconst 於全域宣告。
遮蔽(shadow)變數 同名變數在內層作用域被 := 重新宣告,可能導致意外的值被使用。 盡量避免在同一區塊內同名變數,或使用 var 明確重新賦值。
忘記初始化 var x int 只會得到零值,若預期是其他值會產生邏輯錯誤。 若需要非零初始值,務必在宣告時賦值或使用 :=
多變數同時使用 := 時的型別不一致 a, b := 1, "two" 會推斷 aintbstring,若後續想把 b 改為 int 會出錯。 確認每個變數的型別需求,必要時使用 var 明確指定。
使用 var 但忘記 = var x int 5 會編譯錯誤。 正確語法是 var x int = 5var x = 5(型別推斷)。

最佳實踐

  1. 全域變數:使用 var(或 const)並加上說明性註解。
  2. 局部變數:優先使用 :=,讓編譯器自動推斷型別。
  3. 避免遮蔽:在同一函式內,若需要重新賦值,直接使用 = 而非 :=
  4. 保持一致的宣告風格:團隊可以制定「變數宣告規範」,例如「所有函式入口參數使用明確型別」等。
  5. 善用 IDE / go vet:這些工具會提醒未使用的變數、遮蔽問題與零值使用情形。

實際應用場景

1. 設定檔與環境變數

在微服務或 CLI 應用中,常需要讀取環境變數並轉型。使用 var 配合 os.Getenv 可以清楚表達「此變數可能為空」的意圖。

package main

import (
    "fmt"
    "os"
    "strconv"
)

var (
    // 這裡使用 var,因為它是全域設定
    Port int
)

func init() {
    // 讀取環境變數,若未設定則使用預設值 8080
    pStr := os.Getenv("APP_PORT")
    if pStr == "" {
        Port = 8080
    } else {
        if p, err := strconv.Atoi(pStr); err == nil {
            Port = p
        } else {
            fmt.Println("APP_PORT 不是有效的數字,使用預設 8080")
            Port = 8080
        }
    }
}

func main() {
    fmt.Printf("伺服器將在 %d 埠口啟動\n", Port)
}

2. 迴圈內的計數器

for 迴圈中,使用短宣告 := 可以讓計數器的生命週期僅限於迴圈內,避免意外泄漏。

package main

import "fmt"

func main() {
    numbers := []int{5, 10, 15}
    for i, n := range numbers {
        // i, n 只在此迴圈作用域內有效
        fmt.Printf("第 %d 個元素 = %d\n", i, n)
    }
    // 這裡若嘗試使用 i、n 會編譯錯誤
}

3. 立即函式(IIFE)與資源釋放

在需要快速建立暫時變數、執行完畢即釋放的情境(例如測試、一次性計算),可以結合 := 與匿名函式。

package main

import "fmt"

func main() {
    // 立即執行函式,裡面的變數只在此作用域內
    result := func() int {
        tmp := 42 // 只在此匿名函式內部
        return tmp * 2
    }()

    fmt.Println("計算結果 =", result)
}

總結

  • var:= 是 Go 中最核心的兩種變數宣告方式,各有適用範圍。
  • var:適合全域、需要明確型別或零值初始化的情境。
  • :=:在函式內部快速宣告、型別推斷、保持程式碼簡潔的最佳選擇。
  • 熟悉零值、遮蔽與多變數同時宣告的細節,可避免常見的 runtime 錯誤。
  • 在實務開發中,結合最佳實踐(避免遮蔽、明確註解、使用工具檢查)能讓程式碼更安全、易讀、易維護。

掌握了變數的正確宣告與初始化,你就能在 Go 專案中自信地管理資料、撰寫乾淨的程式碼,為後續的函式、結構體、介面等更高階概念奠定堅實基礎。祝你在 Go 的旅程中一路順風! 🚀