May 5 2014

Nil Channels Always Block

In this post, we will discuss a useful idiom in Go that makes use of the fact that receiving and sending on nil channels will always block:

// Create an uninitialized (nil) channel.
var ch chan struct{}

// Receiving on a nil channel blocks forever.
<-ch

// Sending on a nil channel will also block forever.
ch <- struct{}{}

This might not seem very useful at first, and may have even introduced bugs in your programs in the past (for example, if you forget to initialize your channels with make before you use them). However, this property can be leveraged in a couple of clever ways, especially when you need to dynamically disable a case in a select statement:

May 4 2014

Arrays vs Slices

This post will briefly describe the differences between arrays and slices in Go. It assumes that you have completed A Tour of Go and have consulted relevant sections of Effective Go and the target audience is primarily newcomers to the Go programming language.

Arrays are fixed-length sequences of items of the same type. Arrays in Go can be created using the following syntaxes:

[N]Type
[N]Type{value1, value2, ..., valueN}
[...]Type{value1, value2, ..., valueN}

Unlike in C/C++ (where arrays act like pointers) and Java (where arrays are object references), arrays in Go are values. This has a couple of important implications: (1) assigning one array to another copies all of the elements, and (2) if you pass an array to a function, it will receive a copy of the array (not a pointer or reference to it).

Apr 25 2014

= vs :=

This post will briefly describe the differences between the assignments and short variable declarations in Go. It assumes that you have completed A Tour of Go and have consulted relevant sections of Effective Go and the target audience is primarily newcomers to the Go programming language.

The assignment operator (=) is used to perform assignments (i.e. to assign or reassign values to already declared variables).

The short declaration operator (:=), on the other hand, is used to perform short variable declarations), which are shorthand for regular variable declarations but without a specified type.

Apr 24 2014

Exiting Multiple Goroutines Simultaneously

The ability to close channels (using Go’s builtin close() function) forms the basis of a useful pattern in Go: using a single channel to exit multiple goroutines.

Let’s say we have launched a variable number of goroutines in the background as follows:

shutdown := make(chan struct{})
done := make(chan int)

for i := 0; i < n; i++ {
	i := i
	go func() {
		select {
		case <-shutdown:
			done <- i
		}
	}()
}
Apr 23 2014

new() vs make()

This post will briefly describe the differences between the builtin new() and make() functions in Go. It assumes that you have completed A Tour of Go and have consulted relevant sections of Effective Go and the target audience is primarily newcomers to the Go programming language.

The builtin new(T) function allocates “zeroed” storage for a new item of type T and returns its address, a value of type *T. In Go terminology, it returns a pointer to a newly allocated zero value of type T. For example, here are three different ways to create a pointer p that points to a zeroed bytes.Buffer value, each of which are equivalent:

// Allocate enough memory to store a bytes.Buffer value
// and return a pointer to the value's address.
var buf bytes.Buffer
p := &buf

// Use a composite literal to perform allocation and
// return a pointer to the value's address.
p := &bytes.Buffer{}

// Use the new function to perform allocation, which will
// return a pointer to the value's address.
p := new(bytes.Buffer)

+1 this blog!

Go Design Patterns is a website for developers who wish to better understand the Go programming language. The tutorials here emphasize proper code design and project maintainability.

Find a typo?

Submit a pull request! The code powering this site is open-source and available on GitHub. Corrections are appreciated and encouraged! Click here for instructions.