I've always found the package.New() syntax in go rather awkward to work with.
The suggestion is that if a package holds only a single type, using package.New() to create an instance; if multiple types exist, using package.NewBlah(). http://golang.org/doc/effective_go.html#package-names
However, this approach falls down if you if you have an existing package with a New() api, adding a new external type to the package breaks the api, because you must now rename this NewFoo(). Now you have to go and change anything that uses New(), which is deeply irritating.
...and I'm just discontent with the aesthetic of writing this:
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()
So, recently I've been using this pattern instead:
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
Where the module is defined something like this:
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 seems to work fine with it, and it seems more obvious and consistent to me, without additional verbosity.
So, question: Is there any tangible downside to this?