Variables

Table of Contents

Declare Variables howto

var name type = expression

There is also a concise syntax called Short Variable Declarations:

name := expression
Variables with no expression part are initialized with zero-value
var i, j, k int                  // int, int, int
var b, f, s = true, 2.4, "hello" // bool, float64, string

i := 10      // used only within a function.
x, y := 0, 1

var f float64 = 10
var names []string
var err error
var p Point
:= does not necessarily declare all the variables on its left-hand side

The new Function discussion

p := new(int)
fmt.Println(*p)
*p = 2
fmt.Println(*p)
0
2

Following two functions are equivalent:

func newInt() *int {
    return new(int)
}

func newInt() *int {
    var dummy int
    return &dummy
}

new(T) for types with no data, such as struct{} or [0]int, new() will return the same addresses between multiple calls. Otherwise, it will allocate memory for each call.

Scoping and Lifetime of Variables discussion

Package-level variables
  • Visible not only throughout the source file that contains its declaration, but throughout all the files of the package.
  • So, the lifetime of a package-level variable is the entire execution of the program
Local variables
  • Visible only within the declared block
  • Created each time the declaration statement is executed and live on until they become unreachable.
  • A compiler may choose to allocate local variables on the heap or on the stack.
v := 1
{
  v = 2  // assignment
  fmt.Println(v)
}
fmt.Println(v)
2
2
v := 1
{
    v := 2  // short variable declaration
    fmt.Println(v)
}
fmt.Println(v)
2
1

About Pointers discussion

x := 1
p := &x
fmt.Println(*p)
*p = 2
fmt.Println(x)
1
2
package main
import "fmt"

func incr(p *int) int {
    *p++ // increments what p points to; does not change p
    return *p
}

func main() {
  v := 1
  incr(&v)              // side effect: v is now 2
  fmt.Println(incr(&v)) // "3" (and v is 3)
}
3

Can I use ++i, instead of i++? discussion

Constants discussion

const pi = 3.14159

// or

const (
    e  = 2.71828182845904523536028747135266249775724709369995957496696763
    pi = 3.14159265358979323846264338327950288419716939937510582097494459
)

Many computations on constants can be completely evaluated at compile time, reducing the work necessary at run time and enabling other compiler optimizations.

Since their values are known to the compiler, * constant expressions may appear in types, specifically as the length of an array type*

const IPv4Len = 4
var p [IPv4Len]byte

You can use iota to simplify const declaration, which is replaced with incremental numbers from 0:

const (
    Sunday Weekday = iota
    Monday
    Tuesday
    Wednesday
    Thursday
    Friday
    Saturday
)

Many constants are not committed to a particular type. The compiler represents these uncommitted constants with much greater numeric precision than values of basic types, and arithmetic on them is more precise than machine arithmetic; you may assume at least 256 bits of precision.