单例模式,全局只有一个实例,无法再新建

饿汉模式:提前创建实例,提供一个对外方法,返回此实例
代码如下:

// Singleton 饿汉式单例, 都使用小写,无法导出,外部包没法直接创建
type singleton struct{
	name string
}

// 通过一个导出类型暴露出去*singleton,由于Singleton内部属性无法导出,所以外部也没法创建(只能创建一个空对象)
type Singleton struct {
	*singleton
}

var single *Singleton

func init() {    // 提前创建好的一个实例,通过GetInstance方法,获取到的实例都是这个
	single = &Singleton{&singleton{name: "test"}}

}

func (s *Singleton)GetName() string {
	return s.name
}

// GetInstance 获取实例
func GetInstance() *Singleton {
	return single
}

饱汉模式:熟称懒加载,就是在你使用实例的时候才去加载,对于懒汉模式,由于没有提前加载,在并发条件下,可能会出现两个协程同时去创建,一开始判断都是nil,会出现重复创建,所以需要进行双检(存在性检查,是否有别的协程已经调用创建,go的话我们用once.Do实现)
代码如下:

import (
	"fmt"
	"sync"
)

var (
	lazySingleton *Singleton
	once          = &sync.Once{}
)

// GetLazyInstance 懒汉式
func GetLazyInstance() *Singleton {
	if lazySingleton == nil {   // 检测对象是否存在
		once.Do(func() {      //保证并发条件下值创建一次对象
			fmt.Println("create")
			lazySingleton = &Singleton{&singleton{name: "test lazy"}}
		})
	}
	return lazySingleton
}

func main() {
	wait := sync.WaitGroup{}
	wait.Add(10)
	for i:= 0;i<10;i++ {
		go func() {
			defer wait.Done()
			s := create.GetLazyInstance()
			fmt.Println(s.GetName())
		}()
	}
	wait.Wait()
}