最简单的一种,懒汉模式(非并发)
package main
import "fmt"
var instance *single
type single struct {
Name string
}
func GetInstance() *single {
if instance == nil {
instance = &single{}
}
return instance
}
func main() {
a := GetInstance()
a.Name = "a"
b := GetInstance()
b.Name = "b"
//0xc0000761d0 &{b}
//0xc0000761d0 &{b}
//0xc0000761d0 *main.single
//0xc0000761d0 *main.single
fmt.Println(&a.Name, a)
fmt.Println(&b.Name, b)
fmt.Printf("%p %T\n", a, a)
fmt.Printf("%p %T\n", b, b)
}
懒汉模式加锁
package main
import (
"fmt"
"sync"
)
var instance *single
var lock sync.Mutex
type single struct {
Name string
}
func GetInstance() *single {
lock.Lock()
defer lock.Unlock()
if instance == nil {
instance = &single{}
}
return instance
}
func main() {
a := GetInstance()
a.Name = "a"
b := GetInstance()
b.Name = "b"
//0xc0000101f0 &{b}
//0xc0000101f0 &{b}
//0xc0000101f0 *main.single
//0xc0000101f0 *main.single
fmt.Println(&a.Name, a)
fmt.Println(&b.Name, b)
fmt.Printf("%p %T\n", a, a)
fmt.Printf("%p %T\n", b, b)
}
双重锁机制
package main
import (
"fmt"
"sync"
)
var instance *single
var lock sync.Mutex
type single struct {
Name string
}
func GetInstance() *single {
if instance == nil {
lock.Lock()
defer lock.Unlock()
if instance == nil {
instance = &single{}
}
}
return instance
}
func main() {
a := GetInstance()
a.Name = "a"
b := GetInstance()
b.Name = "b"
//0xc000098040 &{b}
//0xc000098040 &{b}
//0xc000098040 *main.single
//0xc000098040 *main.single
fmt.Println(&a.Name, a)
fmt.Println(&b.Name, b)
fmt.Printf("%p %T\n", a, a)
fmt.Printf("%p %T\n", b, b)
}
go语言自带一个很优雅的写法
package main
import (
"fmt"
"sync"
)
var instance *single
var once sync.Once
type single struct {
Name string
}
func GetInstance() *single {
once.Do(func() {
instance = &single{}
})
return instance
}
func main() {
a := GetInstance()
a.Name = "a"
b := GetInstance()
b.Name = "b"
//0xc0000741e0 &{b}
//0xc0000741e0 &{b}
//0xc0000741e0 *main.single
//0xc0000741e0 *main.single
fmt.Println(&a.Name, a)
fmt.Println(&b.Name, b)
fmt.Printf("%p %T\n", a, a)
fmt.Printf("%p %T\n", b, b)
}
Go打印
- %v 按值的本来值输出
- %+v 在 %v 基础上,对结构体字段名和值进行展开
- %#v 输出 Go 语言语法格式的值
- %T 输出 Go 语言语法格式的类型和值
- %% 输出 % 本体
- %b 整型以二进制方式显示
- %o 整型以八进制方式显示
- %d 整型以十进制方式显示
- %x 整型以十六进制方式显示
- %X 整型以十六进制、字母大写方式显示
- %U Unicode 字符
- %f 浮点数
- %p 指针,十六进制方式显示