Declaring Variables
How var declares a variable with a type, with a value, or with both, and when Go works the type out for you.
var name Type = value // leave out the Type or the value, but not bothA variable is a name for a value. The name lets you use that value further down, and change it later. Go creates one with the keyword var.
The three shapes
var count intgives a type and no value. Go fills in that type's zero value, which forintis 0.var count int = 7gives both the type and the value.var count = 7gives only the value. The compiler works the type out from it. That is called inference.
You may leave out the type or the value. You may not leave out both, because then nothing says what the variable is.
What inference picks
Inference uses the value's default type. A whole number such as 7 gives int. A number with a decimal point gives float64. Text in double quotes gives string. true and false give bool. When you need a different type, write it down: var size int64 = 7.
Where a var can go
A var written outside every function, at the top level of a file, is a package-level variable. Every function in that package can read and change it. A var written inside a function belongs to that function and disappears when the function ends. Several declarations can be grouped under one var keyword in parentheses, which is how most packages list their top-level variables.
What trips people up
Declaring a variable inside a function and never using it is a compile error, not a warning. The program will not build. Either use the value or delete the line.
Example
package main
import "fmt"
// A package-level variable sits outside every function.
var siteName = "soundscode"
func main() {
// Type given, no value: count starts at the zero value for int, which is 0.
var count int
// Type and value both given.
var price float64 = 9.99
// Value only: the compiler infers the type string from "hello".
var greeting = "hello"
// One var keyword can declare a whole group.
var (
width = 3
height = 4
)
// No var keyword here. This is assignment to a variable that already exists.
count = width * height
fmt.Println(siteName, greeting, price)
fmt.Println("count:", count)
}
// Output:
// soundscode hello 9.99
// count: 12When to use it
- Holding a running count or total that a function updates as it works.
- Setting a package-level default, such as a service name, in exactly one place.
- Declaring a value as int64 because the library you are about to call requires that type.
- Listing all of a package's configurable variables in one grouped var block.
More examples
Choosing the type instead of letting Go choose
Libraries often demand an exact type, for example int64 for a byte count or float32 for graphics data. Writing the type in the declaration is how you get it. Reach for this whenever the value will be passed to something that insists on a particular numeric type.
// Inference gives these the default types int and float64.
var count = 7
var ratio = 1.5
// When a specific type is needed, name it. Inference would have
// picked int and float64 again.
var fileSize int64 = 7
var temperature float32 = 1.5
// A whole number can still start a float64 variable.
var limit float64 = 7One var keyword, several names
The grouped form keeps a package's top-level variables in one readable block instead of a column of repeated var keywords. Note the last line: inside a group you can still declare a name with only a type, and it takes its zero value.
// Three names, one type, no values: all three hold 0.
var x, y, z int
// Three names with values. Each type is inferred on its own.
var host, port, secure = "localhost", 8080, true
// A grouped declaration, the usual shape for package-level settings.
var (
appName = "soundscode"
maxRetries = 3
debug bool
)Declaration and assignment are different things
Beginners often write var twice for the same name, which fails with "attempts redeclared in this block". Declare once, then assign as often as you like. This matters as soon as a value changes over the life of a function.
package main
import "fmt"
func main() {
var attempts int // declaration: the variable comes into existence
attempts = 1 // assignment: it already exists, so no var keyword
attempts = attempts + 1
fmt.Println(attempts)
}
// Output:
// 2
Discussion