单例模式可以说是最简单的设计模式之一了,功能很简单:一个类型的东西只实例化一次,全局只有一个实例,并提供方法来获取该实例。
在 Golang 中变量或说明实例只初始化一次的效果通过init函数是可以实现的,包在被引入时就会执行一次init函数且无论同一包被引入多少次也都只执行一次。
不过本文主要想讨论的单例模式是第一次需要用到时才去初始化,也就是延迟初始化。
// bad_singleton.go
package main
import (
"sync"
)
var svcMu sync.Mutex
var svc *Svc
type Svc struct {
Num int
}
func GetSvc() *Svc {
if svc == nil {
// 这一步判断不是并发安全的
svcMu.Lock()
defer svcMu.Unlock()
if svc == nil {