在Go中初始化空字符串的惯用方式

In Go you can initialise an empty string (in a function) in the following ways:

var a string
var b = ""
c := ""

As far as I know, each statement is semantically identical. Is one of them more idiomatic than the others?

You should choose whichever makes the code clearer. If the zero value will actually be used (e.g. when you start with an empty string and concatenate others to it), it's probably clearest to use the := form. If you are just declaring the variable, and will be assigning it a different value later, use var.

There isn't a right way to declare empty variables, but there are some things to keep in mind, like you can't use the := shortcut outside of a function body, as they can with var:

var (
    name string
    age  int64
)

I find var name = "" to be the clearest indication that you're declaring an empty variable, but I like the type explicitness of var name string. In any case, do consider where you are declaring variables. Sometimes all at once outside the function body is appropriate, but often nearest to where you actually use it is best.

rob (Pike?) wrote on a mailthread about top-level declaration

At the top level, var (or const or type or func) is necessary: each item must be introduced by a keyword for ur-syntactic reasons related to recognizing statement boundaries. With the later changes involving semicolons, it became possible, I believe, to eliminate the need for var in some cases, but since const, type, and func must remain, it's not a compelling argument.

There is a certain ambiguity in "short-variable" declarations (using :=), as to whether the variable is declared or redeclared as outlined in the specs:

Unlike regular variable declarations, a short variable declaration may redeclare variables provided they were originally declared earlier in the same block (or the parameter lists if the block is the function body) with the same type, and at least one of the non-blank variables is new. As a consequence, redeclaration can only appear in a multi-variable short declaration. Redeclaration does not introduce a new variable; it just assigns a new value to the original.

There is absolutely no difference in the generated code (with the current compiler – Go 1.7.4), and also gometalinter does not complain for any of those. Use whichever you like.

Some differences:

  • You can only use the short variable declaration in functions.
  • With short variable declaration, you can create variables of multiple types in one line, e.g.

    a, b := "", 0
    

The following 3 apps generate identical code:

a.go

package main
import "fmt"
func main() { var a string; fmt.Println(a) }

b.go

package main
import "fmt"
func main() { var a = ""; fmt.Println(a) }

c.go

package main
import "fmt"
func main() { a := ""; fmt.Println(a) }

To verify, build each (e.g. with go build -o a), and use diff on Linux to compare the executable binaries:

diff a b && diff a c
var a string

It's not immediately visible that it's the empty string for someone not really fluent in go. Some might expect it's some null/nil value.

var b = ""

Would be the most explicit, means everyone sees that it's a variable containing the empty string.

b := ""

The := assigment is so common in go that it would be the most readable in my opinion. Unless it's outside of a function body of course.

I try to stick to the short declaration for a couple of reasons.

  1. It's shorter
  2. Consistency
  3. Allocates memory for maps, slices and pointers to structs and types.

Although var a string and a := "" are the same, b := []T{} and var b []T are not the same. When dealing with slices and maps the shorter declaration will not be nil. More often then not (especially with maps) I want allocated memory.

There are few situations where var will be needed, for instance, you are calling a function that will populate a property of a type.

var err error
foo.Name, err = getFooName()

Using := syntax in the above situation will error out since foo.Name is already declared.