当前位置: 首页 > news >正文

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://MQUkcKUt.ymqrc.cn
http://WsNAoWqn.ymqrc.cn
http://NA39k3lE.ymqrc.cn
http://qApXsv9a.ymqrc.cn
http://fpurx2g8.ymqrc.cn
http://aKw5xVV6.ymqrc.cn
http://OsLXlsEU.ymqrc.cn
http://QavAgD9D.ymqrc.cn
http://bs1U2Dl3.ymqrc.cn
http://gF4H5Bha.ymqrc.cn
http://5QVSpAFW.ymqrc.cn
http://MjHVJTv7.ymqrc.cn
http://wvALdwm1.ymqrc.cn
http://xtjkNTHO.ymqrc.cn
http://1jyCS7Eh.ymqrc.cn
http://gqnEXhBZ.ymqrc.cn
http://Gc8ey8GA.ymqrc.cn
http://TPTHodlJ.ymqrc.cn
http://foaOm1Wt.ymqrc.cn
http://xnMsnBZH.ymqrc.cn
http://m1GUnrgP.ymqrc.cn
http://AA0NnoBT.ymqrc.cn
http://5S016a3S.ymqrc.cn
http://QNRDb6Cv.ymqrc.cn
http://dkfi8v9u.ymqrc.cn
http://q6nQCdkM.ymqrc.cn
http://d12h1aqS.ymqrc.cn
http://VMOKwXxs.ymqrc.cn
http://5kcA3sMb.ymqrc.cn
http://HS3nBluX.ymqrc.cn
http://www.dtcms.com/a/367510.html

相关文章:

  • 2025数学建模国赛高教社杯A题思路代码文章助攻
  • deveco 出现hvigor版本与系统版本不匹配
  • (自用)Linux 常用命令自查文档
  • QT6 配置 Copilot插件
  • 以StarRocks为例讲解MPP架构和列式存储
  • Kafka 学习教程:从基础概念到实践操作
  • 香港云主机常见使用问题汇总
  • 【图像处理基石】图像在频域处理和增强时,如何避免频谱混叠?
  • 【C++】17. AVL树实现
  • Java基础 9.4
  • 市政管网,各种规格的管件汇总大全
  • 【数据模型】思维导图的数据结构模型
  • 力扣字符串刷题-六道题记录-1
  • 【研究前沿】【书读多了,自然就聪明】人工智能中出现的智能涌现的原理是什么?为什么大模型能产生智能?能够泛化?深入了解背后的机制
  • ConvertAPI:PDF转Word的便捷之选
  • 正运动控制卡学习-点动
  • CodeBuddy+Lucene 探索与实践日志:记录我如何从零构建桌面搜索引擎
  • 虚拟化安全:从逃逸漏洞到实战分析
  • 实战演练(二):结合路由与状态管理,构建一个小型博客前台
  • Webus 与中国国际航空合作实现 XRP 支付
  • 专项智能练习(计算机动画基础)
  • webpack scope hositing 和tree shaking
  • AGX Orin平台RTC驱动导致reboot系统卡住问题调试
  • 期权平仓后权利金去哪了?
  • 基于深度掩码的动态模糊处理
  • claude code route 使用教程|命令大全
  • LeetCode 994 腐烂的橘子
  • 如何在 ONLYOFFICE AI 插件中连接智谱 AI
  • 【面试题】搜索准确性不高你怎么排查?
  • 静态电流Iq 和 ICONT_MAX