The Go Handbook - DevTwitter
The Go Handbook - DevTwitter
The Go Handbook - DevTwitter
me/DevTwitter
Table of Contents
Preface
The Go Handbook
Conclusion
t.me/DevTwitter
1
Preface
The Go Handbook follows the 80/20 rule: learn in 20% of the time the 80%
of a topic.
Enjoy!
t.me/DevTwitter
2
The Go Handbook
1. Preface
2. Getting started with Go
3. Install Go
4. Setup your editor
5. Hello, World!
6. Compiling and running the Go program
7. The workspace
8. Diving into the language
9. Variables
10. Basic types
11. Strings
12. Arrays
13. Slices
14. Maps
15. Loops
16. Conditionals
17. Operators
18. Structs
19. Functions
20. Pointers
21. Methods
22. Interfaces
23. Where to go from here
1. Preface
Go is an awesome, simple, modern, fast programming language.
t.me/DevTwitter
3
make their projects compile (and run) faster
be simple so people can pick it up in little time
be low level enough but also avoid some pitfalls of being too low level
be portable (compiled Go programs are binaries that do not require
other files to run and are cross-platform, so they can be distributed
easily)
be boring, stable, predictable, offer less opportunities to make mistakes
make it easy to take advantage of multiprocessor systems
and it was meant to be a replacement for C and C++ codebases some things
simpler, like concurrency or memory management, with garbage collection.
Also, it was built to work along with C and C++ codebases, thanks to its C
interoperability features.
Go can be used for many different needs, and it can solve both simple needs
and very complex ones.
You can create command line utilities, networking servers, and it is widely
used in many different scenarios.
There’s lots of different widely used tools that use this programming
language under the hood.
t.me/DevTwitter
4
First, https://go.dev is the homepage of the language. This will be your go-to
resource to:
3. Install Go
Go to https://go.dev/doc/install and download the package for your
Operating System.
Run the installer, and at the end of the process you will have the go
t.me/DevTwitter
5
Open the terminal and run go version and you should see something like
this:
t.me/DevTwitter
6
NOTE: you might have to open a new terminal before you can run the
program, as the installer added the Go binaries folder to the path.
The exact location of the Go installation files will depend on your Operating
System.
The Windows and Mac installers will set the Go binaries path automatically.
On a Mac you might also want to install Go via Homebrew using brew
On Linux you will have to add the Go binaries folder to your terminal path
before you can run the go command after unpackaging the Linux package
to /usr/local/go with
Read Go in Visual Studio Code for a quick “up and running” setup. At the
bare miminum, install the Go extension.
t.me/DevTwitter
7
This extension will make your life easier providing IntelliSense (syntax
highlighting, autocompletion, on hover information, error highlighting…)
and other things like auto formatting, menu options to install packages,
testing, and more.
5. Hello, World!
Now we’re ready to create our first Go program!
It’s a programmers tradition to make the first program print the “Hello,
World!” string to the terminal when it’s ran. So we’ll do that first, and then
we’ll explain how we did it.
Maybe you have a folder in your home directory where you keep all your
coding projects and tests.
t.me/DevTwitter
8
In there, create a hello.go file (it can be named as you want).
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
package main
9
A package can be composed by multiple files, or just one file.
The main package is the entry point of the program and identifies an
executable program.
import "fmt"
We have a large standard library ready to use that we can use for anything
from network connectivity to math, crypto, image processing, filesystem
access, and more.
You can read all the features that this fmt package provides on the official
documentation.
func main() {
What’s a function? We’ll see more about them later, but in the meantime let’s
say a function is a block of code that’s assigned a name, and contains some
instructions.
The main function is special because what’s where the program starts.
In this simple case we just have one function, the program starts with that
and then ends.
fmt.Println("Hello, World!")
t.me/DevTwitter
10
This is the content of the function we defined.
Take a look at the docs because they are great. They even have examples you
can run:
After the code executes the main function, it has nothing else to do and the
execution ends.
11
go run hello.go
Our program ran successfully, and it printed “Hello, World!” to the terminal!
The go run tool first compiles and then runs the program specified.
go build hello.go
This will create a hello file that’s a binary you can execute:
t.me/DevTwitter
12
In the introduction I mentioned Go is portable.
Now you can distribute this binary and everyone can run the program as-is,
because the binary is already packaged for execution.
We can create a different binary for a different architecture using the GOOS
t.me/DevTwitter
13
Setup for 64-bit macOS (Intel or Apple Silicon) is GOOS=darwin GOARCH=amd64
7. The workspace
One special thing about Go is what we call workspace.
By default Go picks the $HOME/go path, so you will see a go folder in your
home.
It’s first created when you install a package (as we’ll see later) but also to
store some tooling. For example the moment I loaded the hello.go file in
VS Code, it prompted me to install the [gopls]
t.me/DevTwitter
14
When you will install packages using go install , they will be stored here.
This is useful when working on different projects at the same time and you
want to isolate the libraries you use.
15
When we install Go we also get access to the gofmt command line tool
which we can use to format Go programs. VS Code uses that under the hood
to format Go source files.
This is very interesting and innovative because formatting and issues like
tabs vs spaces or “should I put the curly brackets on the same line of the loop
definition or in the next line” are a huge waste of time.
t.me/DevTwitter
16
// this is a line comment
/*
multi
line
comment
*/
9. Variables
One of the first things you do in a programming language is defining a
variable.
var age = 20
package main
import "fmt"
var age = 20
func main() {
fmt.Println("Hello, World!")
}
or inside a function:
t.me/DevTwitter
17
package main
import "fmt"
func main() {
var age = 20
fmt.Println("Hello, World!")
}
Defined at the package level, a variable is visible across all the files that
compose the package. A package can be composed by multiple files, you just
need to create another file and use the same package name at the top.
Defined at the function level, a variable is visible only within that function.
It’s initialized when the function is called, and destroyed when the function
ends the execution.
var age = 20
We’ll see more about types later, but you should know there are many
different ones, starting with int , string , bool .
We can also declare a variable without an existing value, but in this case we
must set the type like this:
When you know the value you typically use the short variable declaration
with the := operator:
t.me/DevTwitter
18
age := 10
name := "Roger"
For the name of the variable you can use letters, digits and the underscore _
If the name is long, it’s common to use camelCase, so to indicate the name of
the car we use carName
You can assign a new value to a variable with the assignment operator =
If you have a variable that never changes during the program you can declare
it as a constant using const :
const age = 10
//or
Declared variables that are not used in the program raise an error and the
program does not compile.
t.me/DevTwitter
19
You will see a warning in VS Code:
t.me/DevTwitter
20
10. Basic types
Go is a typed language.
var age = 10
We have a lot of different types to represent intergers, you will use int most
of the time, and you might choose a more specialized one for optimization
(not something you need to think about when you are just learning).
An int type will default to be 64 bits when used on a 64 bits system, 32 bits
on a 32 bits system, and so on.
uint is an int that’s unsigned, and you can use this to double the amount
of values you can store if you know the number is not going to be negative.
All the above basic types are value types, which means they are passed by
value to functions when passed as parameters, or when returned from
functions.
t.me/DevTwitter
21
11. Strings
A string in Go is a sequence of byte values.
It’s important to note that unlike other languages, strings are defined only
using double quotes, not single quotes.
len(name) //4
You can access individual characters using square brackets, passing the index
of the character you want to get:
name[0:2] //"te"
name[:2] //"te"
name[2:] //"st"
t.me/DevTwitter
22
Strings are immutable, so you cannot update the value of a string.
Even if you assign a new value to first using an assignment operator, the
value second is still going to be "test" :
Strings are reference types, which means if you pass a string to a function,
the reference to the string will be copied, not its value. But since strings are
immutable, in this case it’s not a big difference in practice with passing an
int , for example.
package main
import (
"strings"
)
t.me/DevTwitter
23
For example we can use the HasPrefix() function to see if a string starts
with a specific substring:
package main
import (
"strings"
)
func main() {
strings.HasPrefix("test", "te") // true
}
12. Arrays
Arrays are a sequence of items of a single type.
t.me/DevTwitter
24
and you can initialize the array with values using:
In this case you can also let Go do some work and count the items for you:
The array cannot be resized, you have to explicitly define the length of an
array in Go. That’s part of the type of an array. Also, you cannot use a
variable to set the length of the array.
Due to this limitation, arrays are rarely used directly in Go, but instead we
use slices (more on them later). Slices use arrays under the hood, so it’s still
necessary to know how they work.
You can access an item in the array with the square brackets notation we
already used in strings to access a single character:
You can set a new value for a specific position in the array:
myArray[2] = "Another"
And you can get the length of an array using the len() function:
len(myArray)
anotherArray := myArray
t.me/DevTwitter
25
or passing an array to a function, or returning it from a function, creates a
copy of the original array.
Let’s make a simple example where we assign a new value to an array item
after copying it. See, the copy didn’t change:
myArray[2] //"Another"
myArrayCopy[2] //"Third"
Remember you can only add a single type of items in an array, so setting the
myArray[2] = 2 for example will raise an error.
13. Slices
A slice is a data structure similar to an array, but it can change in size.
Under the hood, slices use an array and they are an abstraction built on top
of them that makes them more flexible and useful (think about arrays as
lower level).
You will use slices in a way that’s very similar to how you use arrays in higher
level languages.
t.me/DevTwitter
26
var mySlice = []string{"First", "Second", "Third"}
//or
You can create an empty slice of a specific length using the make() function:
You can create a new slice from an existing slice, appending one or more
items to it:
Note that we need to assign the result of append() to a new slice, otherwise
we’ll get a compiler error. The original slice is not modified, we’ll get a brand
new one.
You can also use the copy() function to duplicate a slice so it does not share
the same memory of the other one and is independent:
newSlice := make([]string, 3)
copy(newSlice, mySlice)
If the slice you’re copying to does not have enough space (is shorter than the
original) only the first items (until there’s space) will be copied.
t.me/DevTwitter
27
myArray := [3]string{"First", "Second", "Third"}
mySlice = myArray[:]
Multiple slices can use the same array as the underlying array:
mySlice := myArray[:]
mySlice2 := myArray[:]
mySlice[0] = "test"
fmt.Println(mySlice2[0]) //"test"
Those 2 slices now share the same memory and modifying one slice modifies
the underlying array and causes the other slice generated from the array to be
modified too.
If you know you need to perform operations to the slice, you can request it to
have more capacity than initially needed, so when you need more space, the
space will be readily available (instead of finding and moving the slice to a
new memory location with more space to grow and dispose via garbage
collection of the old location).
As with strings, you can get a portion of a slice using this syntax:
t.me/DevTwitter
28
mySlice := []string{"First", "Second", "Third"}
14. Maps
A map is a very useful data type in Go.
agesMap := make(map[string]int)
You don’t need to set how many items the map will hold.
agesMap["flavio"] = 39
You can also initialize the map with values directly using this syntax:
age := agesMap["flavio"]
You can delete an item from the map using the delete() function in this
way:
t.me/DevTwitter
29
delete(agesMap, "flavio")
15. Loops
One of Go’s best features is to give you less choices.
We first initialize a loop variable, then we set the condition we check for each
iteration to decide if the loop should end, and finally the post statement,
executed at the end of each iteration, which in this case increments i .
We don’t need parentheses around this block, unlike other languages like C
or JavaScript.
Other languages offer different kind of loop structures, but Go only has this
one. We can simulate a while loop, if you’re familiar with a language that
has it, like this:
i := 0
for i < 10 {
fmt.Println(i)
i++
}
t.me/DevTwitter
30
We can also completely omit the condition and use break to end the loop
when we want:
i := 0
for {
fmt.Println(i)
if i < 10 {
break
}
i++
}
numbers := []int{1, 2, 3}
//0: 1
//1: 2
//2: 3
It’s common to use this syntax when you don’t need to use the index:
t.me/DevTwitter
31
for _, num := range numbers {
//...
}
using the special _ character that means “ignore this” to avoid the Go
compiler to raise an error saying “you’re not using the i variable!”.
16. Conditionals
We use the if statement to execute different instructions depending on a
condition:
if age < 18 {
//underage
}
if age < 18 {
//underage
} else {
//adult
}
if age < 12 {
//child
} else if age < 18 {
//teen
} else {
//adult
}
If you define any variable inside the if , that’s only visible inside the if
(same applies to else and anywhere you open a new block with {} )
t.me/DevTwitter
32
If you’re going to have many different if statements to check a single
condition it’s probably better to use switch :
switch age {
case 0: fmt.Println("Zero years old")
case 1: fmt.Println("One year old")
case 2: fmt.Println("Two years old")
case 3: fmt.Println("Three years old")
case 4: fmt.Println("Four years old")
default: fmt.Println(i + " years old")
}
17. Operators
We used some operators so far in our code examples, like = , := and < .
var a = 1
b := 1
var num = 1
num == 1 //true
num != 1 //false
t.me/DevTwitter
33
var num = 1
num > 1 //false
num >= 1 //true
num < 1 //false
num <= 1 //true
1 + 1 //2
1 - 1 //0
1 * 2 //2
2 / 2 //1
2 % 2 //0
var num = 1
num++ // num == 2
num-- // num == 1
t.me/DevTwitter
34
Those are the main ones.
18. Structs
A struct is a type that contains one or more variables. It’s like a collection of
variables. We call them fields. And they can have differnet types.
Note that I used uppercase names for the fields, otherwise those will be
private to the package and when you pass the struct to a function provided
by another package, like the ones we use to work with JSON or database,
those fields cannot be accessed.
and we can access the individual fields using the dot syntax:
flavio.Age //39
flavio.Name //"Flavio"
You can also initialize a new variable from a struct in this way:
t.me/DevTwitter
35
or even initialize it without any value:
flavio := Person{}
//or
flavio.Name = "Flavio"
flavio.Age = 39
Structs are useful because you can group unrelated data and pass it around
to/from functions, store in a slice, and more.
Once defined, a struct is a type like int or string and this means you can
use it inside other structs too:
19. Functions
A function is a block of code that’s assigned a name, and contains some
instructions.
t.me/DevTwitter
36
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
func doSomething() {
doSomething()
A function can accept parameters, and we have to set the type of the
parameters like this:
doSomething(1, 2)
t.me/DevTwitter
37
func sumTwoNumbers(a int, b int) int {
return a + b
}
result := sumTwoNumbers(1, 2)
It’s interesting because many languages only allow one return value.
total := sumNumbers(1, 2, 3, 4)
20. Pointers
Go supports pointers.
t.me/DevTwitter
38
age := 20
Using &age you get the pointer to the variable, its memory address.
When you have the pointer to the variable, you can get the value it points to
by using the * operator:
age := 20
ageptr = &age
agevalue = *ageptr
This is useful when you want to call a function and pass the variable as a
parameter. Go by default copies the value of the variable inside the function,
so this will not change the value of age :
func main() {
age := 20
increment(age)
//age is still 20
}
func main() {
age := 20
increment(&age)
//age is now 21
}
t.me/DevTwitter
39
21. Methods
A function can be assigned to a struct and in this case we call it method.
Example:
func main() {
flavio := Person{Age: 39, Name: "Flavio"}
flavio.Speak()
}
The above example shows a value receiver, it receives a copy of the struct
instance.
This would be a pointer receiver that receives the pointer to the struct
instance:
22. Interfaces
An interface is a type that defines one or more method signatures.
Methods are not implemented, just their signature: the name, parameter
types and return value type.
t.me/DevTwitter
40
Something like this:
Now you could have a function accept any type that implements all the
methods defined by the interface:
func main() {
flavio := Person{Age: 39, Name: "Flavio"}
SaySomething(flavio)
}
41
This handbook is an introduction to the Go programming language.
My suggestion is to pick a program you want to build and just start, learning
the things you need on the way.
t.me/DevTwitter
42
Conclusion
Thanks a lot for reading this book.
t.me/DevTwitter
43