最简单的一种,懒汉模式(非并发)

  1. package main
  2. import "fmt"
  3. var instance *single
  4. type single struct {
  5. Name string
  6. }
  7. func GetInstance() *single {
  8. if instance == nil {
  9. instance = &single{}
  10. }
  11. return instance
  12. }
  13. func main() {
  14. a := GetInstance()
  15. a.Name = "a"
  16. b := GetInstance()
  17. b.Name = "b"
  18. //0xc0000761d0 &{b}
  19. //0xc0000761d0 &{b}
  20. //0xc0000761d0 *main.single
  21. //0xc0000761d0 *main.single
  22. fmt.Println(&a.Name, a)
  23. fmt.Println(&b.Name, b)
  24. fmt.Printf("%p %T\n", a, a)
  25. fmt.Printf("%p %T\n", b, b)
  26. }

懒汉模式加锁

  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. )
  6. var instance *single
  7. var lock sync.Mutex
  8. type single struct {
  9. Name string
  10. }
  11. func GetInstance() *single {
  12. lock.Lock()
  13. defer lock.Unlock()
  14. if instance == nil {
  15. instance = &single{}
  16. }
  17. return instance
  18. }
  19. func main() {
  20. a := GetInstance()
  21. a.Name = "a"
  22. b := GetInstance()
  23. b.Name = "b"
  24. //0xc0000101f0 &{b}
  25. //0xc0000101f0 &{b}
  26. //0xc0000101f0 *main.single
  27. //0xc0000101f0 *main.single
  28. fmt.Println(&a.Name, a)
  29. fmt.Println(&b.Name, b)
  30. fmt.Printf("%p %T\n", a, a)
  31. fmt.Printf("%p %T\n", b, b)
  32. }

双重锁机制

  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. )
  6. var instance *single
  7. var lock sync.Mutex
  8. type single struct {
  9. Name string
  10. }
  11. func GetInstance() *single {
  12. if instance == nil {
  13. lock.Lock()
  14. defer lock.Unlock()
  15. if instance == nil {
  16. instance = &single{}
  17. }
  18. }
  19. return instance
  20. }
  21. func main() {
  22. a := GetInstance()
  23. a.Name = "a"
  24. b := GetInstance()
  25. b.Name = "b"
  26. //0xc000098040 &{b}
  27. //0xc000098040 &{b}
  28. //0xc000098040 *main.single
  29. //0xc000098040 *main.single
  30. fmt.Println(&a.Name, a)
  31. fmt.Println(&b.Name, b)
  32. fmt.Printf("%p %T\n", a, a)
  33. fmt.Printf("%p %T\n", b, b)
  34. }

go语言自带一个很优雅的写法

  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. )
  6. var instance *single
  7. var once sync.Once
  8. type single struct {
  9. Name string
  10. }
  11. func GetInstance() *single {
  12. once.Do(func() {
  13. instance = &single{}
  14. })
  15. return instance
  16. }
  17. func main() {
  18. a := GetInstance()
  19. a.Name = "a"
  20. b := GetInstance()
  21. b.Name = "b"
  22. //0xc0000741e0 &{b}
  23. //0xc0000741e0 &{b}
  24. //0xc0000741e0 *main.single
  25. //0xc0000741e0 *main.single
  26. fmt.Println(&a.Name, a)
  27. fmt.Println(&b.Name, b)
  28. fmt.Printf("%p %T\n", a, a)
  29. fmt.Printf("%p %T\n", b, b)
  30. }

Go打印

  1. %v 按值的本来值输出
  2. %+v 在 %v 基础上,对结构体字段名和值进行展开
  3. %#v 输出 Go 语言语法格式的值
  4. %T 输出 Go 语言语法格式的类型和值
  5. %% 输出 % 本体
  6. %b 整型以二进制方式显示
  7. %o 整型以八进制方式显示
  8. %d 整型以十进制方式显示
  9. %x 整型以十六进制方式显示
  10. %X 整型以十六进制、字母大写方式显示
  11. %U Unicode 字符
  12. %f 浮点数
  13. %p 指针,十六进制方式显示