package main
import (
"fmt"
"sync"
)
// Singleton结构体代表单例对象
type Singleton struct {
// 这里可以定义单例对象需要的各种属性
data string
}
// 定义一个全局变量用于存储单例实例
var instance *Singleton
var once sync.Once
// GetInstance函数用于获取单例实例
func GetInstance() *Singleton {
once.Do(func() {
instance = &Singleton{
data: "初始化的数据",
}
defer func() {
// 这里假设当单例对象不再使用时,可能需要释放一些资源,比如关闭文件描述符等
// 实际应用中根据具体需求编写资源释放代码
fmt.Println("资源释放逻辑(示例)")
}()
})
return instance
}
关键步骤解释:
- 定义Singleton结构体:用于表示单例对象,在这个结构体中可以定义单例对象所需要的各种属性和方法,这里定义了一个
data
字符串属性作为示例。
- 定义全局变量:
instance
:用于存储单例实例,初始值为nil
,体现懒加载特性,只有在第一次调用GetInstance
时才会初始化。
once
:sync.Once
类型变量,Go语言提供的用于确保某段代码只执行一次的工具,在并发环境下保证单例实例的唯一性。
- GetInstance函数:
once.Do(func())
:once.Do
方法接受一个函数作为参数,这个函数内的代码只会被执行一次,无论有多少个并发调用GetInstance
。
- 在
Do
方法传入的函数中,初始化instance
为Singleton
结构体实例,并赋予data
初始值,完成单例对象的创建。
defer
语句:在instance
初始化完成后,使用defer
关键字定义一个匿名函数,该函数用于处理资源释放逻辑。虽然这里只是打印了一个示例信息,实际应用中可根据具体资源类型编写对应的释放代码,如关闭数据库连接、文件句柄等。最后返回instance
,使得调用者可以获取到单例实例。这样就通过sync.Once
实现了一个并发安全、懒加载且考虑资源释放的单例模式。