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

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?

Yes, it has a downside. This approach may generate unnecessary garbage - depending on how good the optimization of a specific Go compiler implementation is.

It's not terribly idiomatic and may if done badly create excess garbage as you note. Essentially you are just creating an Init method for your object. I don't use a lot of constructors myself tending to prefer having valid zero values for my objects and only using a constructor if that doesn't hold true.

In your case I think I'd just stop calling the method new and instead call it Init or Setup to better reflect what it's doing. That would avoid giving people the wrong idea about what it's doing.

Edit:

I should have been more detailed here. Calling the method Init or Setup and then using it on a Zero Value would better reflect what is going on to the consumer. eg

f := &foo{}
f.Init()

This avoids the excess garbage and gives you an initializer method as you describe.