猿问

在go中使用静态类型构造函数有什么明显的缺点?

我总是发现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 Foo

y := foo.Bar{}.New()   // <-- Only an additional 3 characters on NewBar{}

o := other.Foo{}.New() // <-- Consistent across all packages, no breakage on update

在定义模块的地方,如下所示:


package foo


type 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似乎可以很好地使用它,并且对我来说似乎更加明显和一致,而无需其他冗长的内容。


所以,问题是:这有没有明显的不利影响?


汪汪一只猫
浏览 174回答 2
2回答

宝慕林4294392

正如您所指出的那样,这不是非常惯用的方法,并且如果做得不好,可能会产生过多的垃圾。本质上,您只是为对象创建一个Init方法。我自己并没有使用很多构造函数,我倾向于倾向于为我的对象使用有效的零值,并且仅在不成立的情况下才使用构造函数。在您的情况下,我想我将不再停止调用new方法,而应将其称为Init或Setup以更好地反映它的作用。这将避免让人们错误地了解它在做什么。编辑:我应该在这里更详细地说明。调用方法Init或Setup,然后在零值上使用它会更好地反映发生在使用者身上的事情。例如f&nbsp;:=&nbsp;&foo{} f.Init()这避免了多余的垃圾,并为您提供了您所描述的初始化方法。
随时随地看视频慕课网APP

相关分类

Go
我要回答