我总是发现package.New()语法很难使用。建议是,如果程序包仅包含单个类型,则使用package.New()创建实例;否则,请执行以下操作:如果存在多个类型,请使用package.NewBlah()。 http://golang.org/doc/effective_go.html#package-names但是,如果您有一个带有New()api的现有程序包,则此方法会失败,因为向该程序包添加新的外部类型会破坏api,因为您现在必须重命名此NewFoo()。现在,您必须去更改使用New()的所有内容,这非常令人恼火。...而我只是对写这篇文章的美学不满意:import "other"import "bar"import "foo"o := other.New() // <-- Weird, what type am I getting? No idea.x := bar.New() y := foo.NewFoo() // <-- Awkward, makes constructor naming look inconsistent z := foo.NewBar() 因此,最近我一直在使用这种模式:x := foo.Foo{}.New() // <-- Immediately obvious I'm getting a Fooy := foo.Bar{}.New() // <-- Only an additional 3 characters on NewBar{}o := other.Foo{}.New() // <-- Consistent across all packages, no breakage on update在定义模块的地方,如下所示:package footype Foo struct { x int}func (s Foo) New() *Foo { // Normal init stuff here return &s // <-- Edit: notice the single instance is returned }type Bar struct {}func (Bar) New() *Bar { return &Bar{} // <-- Edit: Bad, results in double alloc. Not like this. }Godoc似乎可以很好地使用它,并且对我来说似乎更加明显和一致,而无需其他冗长的内容。所以,问题是:这有没有明显的不利影响?
2 回答
宝慕林4294392
TA贡献2021条经验 获得超8个赞
正如您所指出的那样,这不是非常惯用的方法,并且如果做得不好,可能会产生过多的垃圾。本质上,您只是为对象创建一个Init方法。我自己并没有使用很多构造函数,我倾向于倾向于为我的对象使用有效的零值,并且仅在不成立的情况下才使用构造函数。
在您的情况下,我想我将不再停止调用new方法,而应将其称为Init或Setup以更好地反映它的作用。这将避免让人们错误地了解它在做什么。
编辑:
我应该在这里更详细地说明。调用方法Init或Setup,然后在零值上使用它会更好地反映发生在使用者身上的事情。例如
f := &foo{} f.Init()
这避免了多余的垃圾,并为您提供了您所描述的初始化方法。
- 2 回答
- 0 关注
- 173 浏览
添加回答
举报
0/150
提交
取消