代码之家  ›  专栏  ›  技术社区  ›  Ben Noland

围棋中的单打

  •  29
  • Ben Noland  · 技术社区  · 16 年前

    如何在Go编程语言中实现单例设计模式?

    8 回复  |  直到 9 年前
        1
  •  37
  •   esm    10 年前

    抛开实现singleton模式是否是一个好主意的争论,下面是一个可能的实现:

    package singleton
    
    type single struct {
            O interface{};
    }
    
    var instantiated *single = nil
    
    func New() *single {
            if instantiated == nil {
                    instantiated = new(single);
            }
            return instantiated;
    }
    

    single instantiated 是私人的,但是 New() 是公开的。因此,不能直接实例化 单一的 不经过 新() 它用私有布尔值跟踪实例化的数量。 实例化 . 调整的定义 单一的 品尝。

    然而,正如其他几个国家一样 noted ,这不是线程安全的,除非您只是在 init() .更好的方法是利用 sync.Once 为你做艰苦的工作:

    package singleton
    
    import "sync"
    
    type single struct {
            O interface{};
    }
    
    var instantiated *single
    var once sync.Once
    
    func New() *single {
            once.Do(func() {
                    instantiated = &single{}
            })
            return instantiated
    }
    

    另见,哈桑J的建议只是考虑一个包裹 作为 单身汉最后,要考虑其他人的建议:单例常常是一个有问题的实现的指示器。

        2
  •  11
  •   Joe Koberg    16 年前

    在试图找到一种方法屈从于你的意志之前,你可能需要看一些文章:

    总的来说,随着时间的推移,人们发现单胞胎比最优的要差,而且 尤其地 如果您试图进行任何测试驱动的开发:在许多层面上,它们和全局变量一样糟糕。

    [免责声明:我知道这不是对您问题的严格回答,但它确实是相关的]

        3
  •  9
  •   Community Mohan Dere    9 年前

    只需将变量和函数放在包级别。

    另见类似问题: How to make a singleton in Python

        4
  •  8
  •   fabmilo    13 年前

    我认为,在一个并发的世界中,我们需要更清楚地认识到这些行不是原子地执行的:

    if instantiated == nil {
        instantiated = new(single);
    }
    

    我会按照@markermer的建议使用“同步”软件包。

    import "sync"
    
    type MySingleton struct {
    
    }
    
    var _init_ctx sync.Once 
    var _instance *MySingleton
    
    func New() * MySingleton {
         _init_ctx.Do( func () { _instance = new(MySingleton) }  )
         return _instance 
    }
    
        5
  •  5
  •   sadlil    10 年前

    最好的方法是:

     package singleton
    
     import "sync"
    
     type singleton struct {
     }
    
     var instance *singleton
     var once sync.Once
    
     func GetInstance() *singleton {
         once.Do(func() {
             instance = &singleton{}
         })
         return instance
     }
    

    你应该读这个 Link

        6
  •  3
  •   marketer    16 年前

    您可以使用 once package :

    这将确保只调用一次init方法。

        7
  •  1
  •   BalusC    16 年前

    只需要一个静态的、最终的、常量的、全局的、应用程序范围的对象实例。

    然而,这与OO范式相矛盾。它的使用应该局限于原语和不变的对象,而不是可变的对象。

        8
  •  0
  •   Andre Steingress    10 年前

    你应该知道 Once.Do 只执行一次代码。也就是说,代码是 总是 只执行过一次,尽管它可能会惊慌失措:

    https://golang.org/pkg/sync/#Once.Do

    如果f(注意:一旦逻辑)崩溃,do认为它已经返回;do的未来调用将返回而不调用f。

    我使用互斥来确保全局配置变量的唯一初始化,以克服此限制:

    推荐文章