go 初始化組件最佳實踐

Go 語言初始化最佳實踐

在 Go 語言中, 有一個 init() 函數可以對程序進行包級別的初始化, 但 init() 函數有諸多不便, 例如: 無法返回錯誤, 進行耗時初始化時, 會增加程序啟動時間。因此 init() 函數并不適用于所有初始化。

1.初始化方式

在程序進行初始化時,我們應該分析初始化的對象是為: 急切初始化(如: 日志組件, 配置文件讀取) 還是 延遲初始化 (如: 數據庫連接, 消息隊列連接) 。急切初始化大多情況不需要對外部進行連接,且被其他組件所依賴,這時使用 init() 函數進行初始化。延遲初始化對象為需要程序對外部進行連接,且耗時較長, 這時調用 sync.once 進行初始化保證并發安全。

特性延遲初始化使用 init 函數 進行 急切初始化
執行時機首次調用時執行 (懶加載)包被導入時自動執行,在 main 函數之前 (急加載)
并發安全調用 ,專為并發環境設計包初始化由運行時控制,但后續對全局變量的并發訪問需額外同步
錯誤處理可通過封裝返回 error (需自行實現)困難,通常只能 log.Fatalpanic
資源消耗按需分配,避免不必要的啟動開銷程序啟動即分配,可能增加啟動時間和內存占用
典型應用場景數據庫連接池外部服務客戶端重型單例對象配置預加載(輕量)、驅動注冊(如數據庫驅動)、日志系統初始化
可控性高,可靈活控制初始化時機和條件低,由 Go 運行時控制執行順序和時機

2.單例模式

單例模式是一種創建型設計模式,它的核心目標是確保一個結構體只有一個實例,并提供一個全局訪問點來獲取這個實例。這種模式在需要控制資源訪問或確保全局唯一性的場景中非常有用。

單例模式的關鍵在于三點:

  1. 唯一實例:單例結構體必須保證只創建一個對象實例。
  2. 自我創建:單例結構體需要自行創建這個實例。
  3. 全局訪問:單例結構體必須提供一個允許全局訪問該實例的方法。

實現上,通常不允許外部修改結構體,然后提供一個公共方法(如 getInstance())來返回該類的唯一實例。

實現方式描述優點缺點并發安全
餓漢式類加載時就初始化實例。實現簡單,線程安全未使用實例時也會創建,可能浪費內存
懶漢式第一次調用時才創建實例。延遲加載,節省資源需加鎖保證保證安全,性能有開銷

init() 就是餓漢式, 懶漢式 使用 sync.once , 且 sync.once 內部的優化保證了性能和并發安全。

3.代碼示例

餓漢式示例:

package confimport ("fmt""github.com/joho/godotenv""github.com/spf13/viper""log""time"
)type Config struct {App      AppConfig
}var _conf = &Config{}func init() {var v = viper.New()v.SetConfigName("StarMall")v.SetConfigType("toml")v.AddConfigPath("E:/starmall/")v.AutomaticEnv()// 讀取配置文件err := v.ReadInConfig()if err != nil {fmt.Println(err)log.Printf("config load Error: %v \n", err)} else {log.Println("configuration file was read successfully")}// 將 viper 讀到的數據序列化寫入 configif err := v.Unmarshal(&_conf); err != nil {now := time.Now()log.Printf("%v: viper Unmarshal err:%s \n", now.Format("2006-01-02 15:04:05"), err)}
}func GetConfig() *Config {return _conf
}

懶漢式 示例:

package databaseimport ("fmt"_ "github.com/go-sql-driver/mysql""github.com/jmoiron/sqlx""github.com/star-find-cloud/star-mall/conf"log "github.com/star-find-cloud/star-mall/pkg/logger""sync"
)type MySQL struct {Conn *sqlx.DB
}var (_mysql = &MySQL{}once   sync.Once
)func initMysql() (*sqlx.DB, error) {var (_db *sqlx.DBerr error)once.Do(func() {c := conf.GetConfig()user := c.Database.MySQL.Userpasswd := c.Database.MySQL.PasswordHost := c.Database.MySQL.MasterHostPort := c.Database.MySQL.MasterPorttimeout := c.Database.MySQL.TimeoutDSN := fmt.Sprintf("%s:%s@tcp(%s:%d)/?charset=utf8mb4&parseTime=True&timeout=%ss", user, passwd, Host, Port, timeout)_db, err = sqlx.Connect("mysql", DSN)if err != nil {fmt.Println("Database error, please check the logs.")//fmt.Println(c.Database.MySQL)log.MySQLLogger.Errorf("MySQL master connect faild: %s \n", err)} else {log.MySQLLogger.Infof("MySQL master connection successful: %s\n", Host)}_db.SetMaxOpenConns(c.Database.MySQL.MaxOpenConns)_db.SetMaxIdleConns(c.Database.MySQL.MaxIdleConns)})return _db, err
}func NewMySQL() (*MySQL, error) {db, err := initMysql()_mysql.Conn = dbreturn _mysql, err
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/921247.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/921247.shtml
英文地址,請注明出處:http://en.pswp.cn/news/921247.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

域名暫停解析是怎么回事

域名注冊和使用是需要付費的,如果沒有及時續費,域名注冊商就會暫停該域名的解析服務。相關數據顯示,大約有 30% 的域名暫停解析情況是由于欠費引起的。比如,有個小公司的網站域名到期了,負責續費的員工忘記操作&#x…

前端開發的“三劍客”—— ??HTML、CSS、JavaScript??

前端開發的“三劍客”—— ??HTML、CSS、JavaScript??,是構建所有網頁和Web應用的基石。它們分工明確又緊密協作,共同實現了網頁的“內容結構”“視覺表現”和“交互行為”。以下是三者的詳細解析及協作邏輯:??1. HTML:網頁…

TDengine TIMEDIFF() 函數用戶使用手冊

TDengine TIMEDIFF() 函數詳細使用手冊 目錄 功能概述函數語法參數說明返回值說明版本變更說明技術特性使用場景及示例時間單位處理數據類型兼容性注意事項常見問題最佳實踐 功能概述 TIMEDIFF() 函數用于計算兩個時間戳的差值,返回 expr1 - expr2 的結果。結果…

數據結構:棧和隊列(上)

匯總代碼見:登錄 - Gitee.com 上一篇文章:數據結構:雙向鏈表-CSDN博客 與本文相關的結構體傳參:自定義類型:結構體-CSDN博客 1.棧 1.1概念和結構 棧:一種特殊的線性表,其只允許在固定的一端…

文檔抽取技術:提取非結構化文檔中的關鍵信息,提升檔案管理、金融保險和法律合規領域的效率與準確性

在信息爆炸的時代,各種機構、企業等都面臨著海量非結構化文檔數據的挑戰。報告、合同、票據、檔案記錄、法律文書等文檔中蘊藏著巨大的數據,但傳統依靠人工閱讀、理解和錄入的方式效率低下、成本高昂且容易出錯。文檔抽取技術作為人工智能和自然語言處理…

雷柏VT1 MAX評測:原生中小手形電競鼠標 但既不僅限于中小手形 也不僅限于電競

一、前言:真正針對中小手形設計的電競鼠標 雷柏第二代VT系列電競鼠標我們已經體驗過很多款了,基本都是針對大中手形設計的外形模具,只有VT3s系列是VT3系列的縮小版,更適合中小手形使用,但也只是對中大手形模具重新優化…

新客戶 | TDengine 時序數據庫賦能開源鴻蒙物聯展區實時監控與展示

在工業物聯網快速發展的當下,企業普遍面臨著兩大挑戰:一是設備種類繁多、接入標準不一,導致系統建設容易陷入“數據孤島”;二是實時監控和多場景聯動的需求越來越強烈,但傳統數據庫在高頻寫入與多維分析上難以兼顧&…

深入剖析 ConcurrentHashMap:Java 并發編程的基石

目錄 【1】Java 7 中 ConcurrentHashMap 的實現原理 1.分段鎖(Segment) 2. 數據結構 3. 操作流程 【2】Java 8 中 ConcurrentHashMap 的改進 1.紅黑樹的引入 2.CAS 操作 3.數據結構的變化 【3】ConcurrentHashMap 的常用方法及使用示例 1.put(…

【會員專享數據】2020-2022年我國鄉鎮的逐日地表氣壓數據(Shp/Excel格式)

之前我們分享過2020—2022年中國0.01分辨率逐日地表氣壓柵格數據(可查看之前的文章獲悉詳情)!該數據是研究者張凌, 胡英屹等發布在國家冰川凍土沙漠科學數據中心平臺上的高分辨地表氣壓數據。很多小伙伴拿到數據后反饋柵格數據不太方便使用&a…

第二階段WinForm-12:UI控件庫

1_驗證碼與條形碼 1.1_條碼基礎知識 條碼:條碼是由一組按一定編碼規則排列的條、空符號組成,用以表示一定的字符、數字及符號組成的信息 1.2_一維碼 (1)Code 128 Code 128 是一種密度很高的字母數字代碼系統,可對其…

別再誤會了!Redis 6.0 的多線程,和你想象的完全不一樣

技術解析核心誤區:Redis 6.0是完全多線程的嗎?No. Redis 6.0引入的多線程,只用于網絡I/O的讀寫和數據的解析。而核心的命令執行(比如 GET, SET, HGETALL 等)依然是單線程的。Redis的架構演進,就像是把一個復…

23種設計模式——抽象工廠模式(Abstract Factory Pattern)詳解

?作者簡介:大家好,我是 Meteors., 向往著更加簡潔高效的代碼寫法與編程方式,持續分享Java技術內容。 🍎個人主頁:Meteors.的博客 💞當前專欄:設計模式 ?特色專欄:知識分享 &#x…

本地部署開源數據生成器項目實戰指南

本地部署開源數據生成器項目實戰指南 前言 在當今大數據和人工智能時代,高質量數據集對于模型訓練和算法開發至關重要。然而,獲取真實且合規的數據集往往面臨隱私、成本和法律等多重挑戰。合成數據生成技術為此提供了優雅的解決方案,它能夠…

2025React面試題集錦

1. React 是什么?它有哪些主要特點? React 是由Facebook開發的開源JavaScript庫,用于構建用戶界面(UI),尤其適合開發復雜的單頁應用(SPA)。 主要特點: 聲明式編程:只需描述UI應該是什么樣子(如return <div>Hello</div>),React會自動處理DOM更新,無需…

設計模式:迭代器模式(Iterator Pattern)

文章目錄一、概念二、實例分析三、示例代碼一、概念 迭代器模式 是一種 行為型設計模式&#xff0c;用于在不暴露集合對象內部結構的前提下&#xff0c;順序訪問集合中的元素。 換句話說&#xff1a; 集合類只負責數據存儲&#xff1b;迭代器類負責遍歷集合&#xff1b;使用者…

Vue 3 學習路線指南

階段一:基礎入門 (1-2周) 1.1 環境準備 # 安裝 Node.js (推薦 18+ 版本) # 安裝 Vue CLI 或使用 Vite npm create vue@latest my-vue-app cd my-vue-app npm install npm run dev1.2 Vue 3 核心概念 響應式系統:ref(), reactive(), computed() 組合式 API:setup() 函數 模…

使用 `hover:not-[:has(:hover)]` 避免「父元素和子元素同時 hover」時的樣式沖突

:hover:not-(:has(:hover)) has() CSS 4 引入的“父選擇器”&#xff0c;意思是&#xff1a;匹配那些里面包含某個子元素/狀態的元素。 例如&#xff1a;:has(:hover) 表示「自身包含正在被 hover 的子元素」。 :not() 取反偽類&#xff0c;表示不匹配里面的條件。 比如我…

第三十天-DMA串口實驗

一、DMA概述二、DMA通道注意&#xff0c;想要往串口中寫數據&#xff0c;外部請求信號應該是USARTx_TX&#xff0c;當DR寄存器為空時&#xff0c;產生TX信號&#xff0c;請求DMA。反之&#xff0c;從串口中讀數據&#xff0c;外部請求信號應該是USARTx_RX&#xff0c;當DR寄存器…

C/C++ 中的inline(內聯函數關鍵字)詳解

在 C/C 編程中&#xff0c;函數調用雖然帶來了代碼復用和可讀性提升&#xff0c;但頻繁調用小型函數可能會產生額外的調用開銷&#xff08;call overhead&#xff09;&#xff0c;比如棧幀的建立與銷毀、參數傳遞等。 為了減少這種開銷&#xff0c;C 引入了 inline&#xff08;…

2025 年高教社杯全國大學生數學建模競賽A 題 煙幕干擾彈的投放策略完整成品 思路 模型 代碼 結果 全網首發高質量!!!

煙幕干擾彈主要通過化學燃燒或爆炸分散形成煙幕或氣溶膠云團,在目標前方特定空域形成遮蔽&#xff0c;干擾敵方導彈&#xff0c;具有成本低、效費比高等優點。隨著煙幕干擾技術的不斷發展&#xff0c;現已有多種投放方式完成煙幕干擾彈的定點精確拋撒,即在拋撒前能精確控制煙幕…