Book Image

Go Design Patterns

By : Mario Castro Contreras
Book Image

Go Design Patterns

By: Mario Castro Contreras

Overview of this book

Go is a multi-paradigm programming language that has built-in facilities to create concurrent applications. Design patterns allow developers to efficiently address common problems faced during developing applications. Go Design Patterns will provide readers with a reference point to software design patterns and CSP concurrency design patterns to help them build applications in a more idiomatic, robust, and convenient way in Go. The book starts with a brief introduction to Go programming essentials and quickly moves on to explain the idea behind the creation of design patterns and how they appeared in the 90’s as a common "language" between developers to solve common tasks in object-oriented programming languages. You will then learn how to apply the 23 Gang of Four (GoF) design patterns in Go and also learn about CSP concurrency patterns, the "killer feature" in Go that has helped Google develop software to maintain thousands of servers. With all of this the book will enable you to understand and apply design patterns in an idiomatic way that will produce concise, readable, and maintainable software.
Table of Contents (17 chapters)
Go Design Patterns
About the Author
About the Reviewer
Customer Feedback

Arrays, slices, and maps

Arrays are one of the most widely used types of computer programming. They are lists of other types that you can access by using their position on the list. The only downside of an array is that its size cannot be modified. Slices allow the use of arrays with variable size. The maps type will let us have a dictionary like structures in Go. Let's see how each work.


An array is a numbered sequence of elements of a single type. You can store 100 different unsigned integers in a unique variable, three strings or 400 bool values. Their size cannot be changed.

You must declare the length of the array on its creation as well as the type. You can also assign some value on creation. For example here you have 100 int values all with 0 as value:

var arr [100]int 

Or an array of size 3 with strings already assigned:

arr := [3]string{"go", "is", "awesome"} 

Here you have an array of 2 bool values that we initialize later:

var arr [2]bool 
arr[0] = true 
arr[1] = false 


In our previous example, we have initialized an array of bool values of size 2. We wouldn't need to assign arr[1] to false because of the nature of zero-initialization in the language. Go will initialize every value in a bool array to false. We will look deeper to zero-initialization later in this chapter.


Slices are similar to arrays, but their size can be altered on runtime. This is achieved, thanks to the underlying structure of a slice that is an array. So, like arrays, you have to specify the type of the slice and its size. So, use the following line to create a slice:

mySlice := make([]int, 10) 

This command has created an underlying array of ten elements. If we need to change the size of the slice by, for example, adding a new number, we would append the number to the slice:

mySlice := append(mySlice, 5) 

The syntax of append is of the form ([array to append an item to], [item to append]) and returns the new slice, it does not modify the actual slice. This is also true to delete an item. For example, let's delete the first item of the array as following:

mySlice := mySlice[1:] 

Yes, like in arrays. But what about deleting the second item? We use the same syntax:

mySlice = append(mySlice[:1], mySlice[2:]...) 

We take all elements from zero index (included) to the first index (not included) and each element from the second index (included) to the end of the array, effectively deleting the value at the second position in the slice (index 1 as we start counting with 0). As you can see, we use the undetermined arguments syntax as the second parameter.


Maps are like dictionaries--for each word, we have a definition but we can use any type as word or definition and they'll never be ordered alphabetically. We can create maps of string that point to numbers, a string that points to interfaces and structs that point to int and int to function. You cannot use as key: slices, the functions, and maps. Finally, you create maps by using the keyword make and specifying the key type and the value type:

myMap := make(map[string]int) 
myMap["one"] = 1 
myMap["two"] = 2 

When parsing JSON content, you can also use them to get a string[interface] map:

myJsonMap := make(map[string]interface{}) 
jsonData := []byte(`{"hello":"world"}`) 
err := json.Unmarshal(jsonData, &myJsonMap) 
if err != nil { 
fmt.Printf("%s\n", myJsonMap["hello"]) 

The myJsonMap variable is a map that will store the contents of JSON and that we will need to pass its pointer to the Unmarshal function. The jsonData variable declares an array of bytes with the typical content of a JSON object; we are using this as the mock object. Then, we unmarshal the contents of the JSON storing the result of the memory location of myJsonMap variable. After checking that the conversion was ok and the JSON byte array didn't have syntax mistakes, we can access the contents of the map in a JSON-like syntax.