-
22-07-2019 - |
题
如何在Go语言中实现单例设计模式?
解决方案
撇开与否实现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()
是公开的。因此,你不能直接实例single
不通过New()
去,它跟踪与私人布尔instantiated
实例的数量。调整single
品尝的定义中。
然而,由于其他几个具有指出时,这是不线程安全的,除非你只是在初始化的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的建议。最后,不要考虑别人所提出的建议:即单身往往是有问题的执行情况的指标
其他提示
在尝试找到一种让 Go 屈服于你的意愿的方法之前,你可能需要看看一些文章:
总而言之,随着时间的推移,人们发现单例并不是最佳的,恕我直言 尤其 如果您尝试进行任何测试驱动开发:在很多层面上它们几乎和全局变量一样糟糕。
[免责声明:我知道这不是对你问题的严格回答,但它确实相关]
只要把你的变量和函数在包级别。
另见类似的问题:如何使在Python单
我认为,在一个并行的世界我们需要多一点知道这些行不会自动执行:
if instantiated == nil {
instantiated = new(single);
}
我会按照@marketer的建议,并使用包“同步”
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
}
最好的方法将是:
package singleton
import "sync"
type singleton struct {
}
var instance *singleton
var once sync.Once
func GetInstance() *singleton {
once.Do(func() {
instance = &singleton{}
})
return instance
}
您应该阅读链接
可以使用做初始化一旦包:
这将确保您的init方法只被调用一次。
只要有一个单一的静态的,最终的,恒定的,全局的,应用范围所需的对象的实例。
此然而违背了OO范例。它的使用应该限制在原语和不可改变的对象,而不是到可变对象。
你应该知道 Once.Do
认真对待只执行一次代码。这意味着,代码是 总是 只执行一次,即使它可能已经惊慌了:
从 https://golang.org/pkg/sync/#Once.Do
如果 f (注:一旦逻辑)恐慌,Do 认为它已经返回;Do 的未来调用将返回而不调用 f。
我使用互斥体来确保全局配置变量的唯一初始化以克服此限制: