A struct literal denotes a newly allocated struct value by listing the values of its fields. You can list just a subset of fields by using the Name: syntax. (And the order of named fields is irrelevant.) The special prefix & returns a pointer to the struct value.

type Vertex struct {
	X, Y int

var (
	v1 = Vertex{1, 2}  // has type Vertex
	v2 = Vertex{X: 1}  // Y:0 is implicit
	v3 = Vertex{}      // X:0 and Y:0
	p  = &Vertex{1, 2} // has type *Vertex


Remember: a method is just a function with a receiver argument.

func (v Vertex) Abs() float64 {
	return math.Sqrt(v.X*v.X + v.Y*v.Y)

func (v *Vertex) Scale(f float64) {
	v.X = v.X * f
	v.Y = v.Y * f

func Scale(v *Vertex, f float64) {
	v.X = v.X * f
	v.Y = v.Y * f

func main() {
	v := Vertex{3, 4}
	Scale(&v, 10)

Pointer receivers

You can declare methods with pointer receivers. This means the receiver type has the literal syntax *T for some type T. (Also, T cannot itself be a pointer such as *int.)

Methods with pointer receivers can modify the value to which the receiver points (as Scale does here). Since methods often need to modify their receiver, pointer receivers are more common than value receivers.

For the statement v.Scale(5), even though v is a value and not a pointer, the method with the pointer receiver is called automatically. That is, as a convenience, Go interprets the statement v.Scale(5) as (&v).Scale(5) since the Scale method has a pointer receiver.


The Empty Interface

The interface type that specifies zero methods is known as the empty interface:


An empty interface may hold values of any type. (Every type implements at least zero methods.) Empty interfaces are used by code that handles values of unknown type. For example, fmt.Print takes any number of arguments of type interface{}.



A goroutine is a lightweight thread managed by the Go runtime.

go f(x, y, z) starts a new goroutine running f(x, y, z)

Goroutines run in the same address space, so access to shared memory must be synchronized. The sync package provides useful primitives, although you won’t need them much in Go as there are other primitives.


Channels are a typed conduit through which you can send and receive values with the channel operator, <-. (The data flows in the direction of the arrow.)

ch <- v    // Send v to channel ch.
v := <-ch  // Receive from ch, and assign value to v.

By default, sends and receives block until the other side is ready. This allows goroutines to synchronize without explicit locks or condition variables.

Channels can be buffered. Provide the buffer length as the second argument to make to initialize a buffered channel.


The select statement lets a goroutine wait on multiple communication operations. A select blocks until one of its cases can run, then it executes that case. It chooses one at random if multiple are ready.

func fibonacci(c, quit chan int) {
	x, y := 0, 1
	for {
		select {
		case c <- x:
			x, y = y, x+y
		case <-quit:



The type [n]T is an array of n values of type T.

var a [10]int

An array’s length is part of its type, so arrays cannot be resized. This seems limiting, but don’t worry; Go provides a convenient way of working with arrays.


A slice, on the other hand, is a dynamically-sized, flexible view into the elements of an array. In practice, slices are much more common than arrays. The type []T is a slice with elements of type T.

//  A slice is formed by specifying a low and high bound
a[low : high]

// Create a slice which includes elements 1 through 3

A slice does not store any data, it just describes a section of an underlying array.


A slice literal is like an array literal without the length.

// This is an array literal:
[3]bool{true, true, false}

// And this creates the same array as above, then builds a slice that references it:
[]bool{true, true, false}

// Slice literals can contain multiple types