Like Share Discussion Bookmark Smile

J.J. Huang   2025-06-15   Getting Started Golang 07.套件   瀏覽次數:次   DMCA.com Protection Status

Go | 初始化函式的正確使用

💬 簡介

在 Go 語言中,init() 是一個特殊的函式,會在程式啟動與套件載入時自動執行。
雖然設計初衷是為了初始化設定與預備資料,但若使用不當,反而容易造成依賴混亂與維護困難。

本篇將帶你了解 init() 的生命週期、執行順序與建議用法,讓初始化邏輯更加清晰可控。

圖片來源:Gophers


🔍 什麼是 init() 函式?

  • 是 Go 語言保留的特殊函式
  • 無參數、無回傳值,命名必為 init
  • 每個檔案可以有多個 init() 函式
  • 自動執行:在 main() 執行之前就會觸發

🔄 執行順序

  1. 套件層級執行順序
    依照 import 的依賴關係,自下而上初始化。

  2. 單一套件中執行順序

    • 全域變數 → init() 函式(依照原始碼撰寫順序)
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      package main

      import (
      "fmt"
      _ "myapp/config"
      )

      func main() {
      fmt.Println("Main 函式執行")
      }

      config/init.go

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      package config

      import "fmt"

      var AppName string = initName()

      func init() {
      fmt.Println("執行 init():載入設定")
      }

      func initName() string {
      fmt.Println("執行變數初始化")
      return "MyApp"
      }

      執行結果:

      1
      2
      3
      執行變數初始化
      執行 init():載入設定
      Main 函式執行

🎯 init() 的適合用途

使用場景 說明
✅ 一次性設定初始化 如設定預設值、載入必要資源
✅ 註冊機制 如 plugin 註冊、自動掛載路由
✅ 隱式啟動邏輯 flag.Parse() 或註冊第三方資源
✅ 驗證前置條件 僅限不依賴外部變數的快速檢查

🚫 不建議的使用方式

誤用方式 問題
❌ 實作邏輯過多 不易追蹤初始化流程,降低可維護性
❌ 執行順序依賴其他套件 容易因初始化順序錯誤導致錯誤發生
❌ 操作不可預期副作用 隱性修改狀態,程式行為難以預測
❌ 模擬「建構子」邏輯 init() 不該替代明確的初始化函式

📌 建議使用模式

  • ✅ 組合使用明確 API

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    package config

    var Env string

    func init() {
    Env = "production"
    }

    func GetEnv() string {
    return Env
    }
  • ✅ 或改為顯式初始化函式

    1
    2
    3
    4
    5
    6
    7
    package config

    var Env string

    func Init() {
    Env = "production"
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    package main

    import (
    "myapp/config"
    )

    func main() {
    config.Init()
    // 明確控制初始化時機
    }

⚠️ 搭配單元測試的注意

  • init() 在每次測試執行時都會重新執行一次
  • 單元測試中盡量避免依賴 init() 狀態,應設計成可注入或明確初始化的結構

🎯 總結

init() 函式是 Go 語言設計中強大但容易誤用的工具。
正確使用能簡化初始化流程,濫用則可能導致架構混亂。

  • ✅ 僅用於必要的初始化任務
  • ✅ 控制好執行邏輯的輕量與可預測性
  • ✅ 複雜邏輯請轉為顯式函式
  • ✅ 減少跨套件依賴與隱藏副作用

最後建議回顧一下 Go | 菜鳥教學 目錄,了解其章節內容。


註:以上參考了
Go