0% found this document useful (0 votes)
14 views

Go Cheatsheet

This document provides a cheatsheet on practical Go lessons including how to build a program, use slices, work with Go modules, use goimports for imports, write unit tests, and Go naming conventions.

Uploaded by

prsnortin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views

Go Cheatsheet

This document provides a cheatsheet on practical Go lessons including how to build a program, use slices, work with Go modules, use goimports for imports, write unit tests, and Go naming conventions.

Uploaded by

prsnortin
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

Cheatsheet - Practical Go Lessons https://www.practical-go-lessons.

com/chap-42-cheatsheet

Chapter 42: Cheatsheet

1 Build a program
When your main file (that belongs to package main and have a main function) has the following relative path : /my/program/main.go.
Open a terminal and type

$ go build -o binaryName /my/program/main.go

The program will be compiled. A binary named binaryName will be created in the current directory (where you execute the command)

2 Slices
• A growable collection of elements of the same type.

• Size is not known at compile time

• Internally: a pointer to an underlying array

• A good resource for playing with slices is the “Slice Tricks” page1

2.1 Create a slice


• make([]int,0) : a slice of integers with a length 0 and a capacity of 0

• make([]int,0,10) : a slice of integers with a length 0 and a capacity of 10

• Slicing an existing array :

a := [4]int{1,2,3,4}
s = a[:3]
// s = [1,2]
// capacity = 4
// length = 2

s := []int{1,2,3,4} create a slice and fill it directly

2.2 Add elements to slice


s = append(s,0) : Add 0 to the slice s

2.3 Access an element by its index


s[8]

get the element of slice s at index 8. (be careful, the index starts at 0)

1 of 9 02/01/2023, 02:25
Cheatsheet - Practical Go Lessons https://www.practical-go-lessons.com/chap-42-cheatsheet

2.4 Copy
• copy builtin allows copying data from (source) one slice to another (destination)

func copy(destination, source []Type) int

• Destination then source (alphabetical order)

2.5 Empty a slice


a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
a = a[:0]

// OR

a = nil

2.6 Prepend an element to a slice


b := []int{2, 3, 4}
b = append([]int{1}, b...)

2.7 Remove an element at index


a = append(a[:i], a[i+1:]...)

2.8 Find an element in a slice


You will have to iterate over it (with a for loop). Maybe use a map instead?

2.9 Put an element at index


s = append(s, 0)
copy(s[i+1:], s[i:])
s[i] = x

3 Go modules
• Initialize Go modules

$ go mod init yourModulePath

◦ Usually, the module path is an URL of a code-sharing website (GitHub, GitLab, bitbucket ...)
• Upgrade all dependencies to the latest version (minor versions and patches)

$ go get -u

• Upgrade a specific dependency (ex: gitlab.com/loir402/foo)

$ go get gitlab.com/loir402/foo

• Upgrade/Downgrade a specific dependency to a specific revision

$ $ go get module_path@X

Where X can be :

◦ A commit hash

▪ Ex : b822ebd
◦ A version string

▪ Ex : v1.0.3
• Cleanup your go.mod and go.sum file

$ go mod tidy

2 of 9 02/01/2023, 02:25
Cheatsheet - Practical Go Lessons https://www.practical-go-lessons.com/chap-42-cheatsheet

• Print the dependency graph of your module

$ go mod graph

• Create a vendor directory to store all your dependencies

$ go mod vendor

• Check that the dependencies downloaded locally have not been altered

$ go mod verify

• List all dependencies along with their version

◦ This list is also known as the build list [@minimal-version-cox]


$ go list -m all

The paper and the digital edition of this book are available here. ×
I also filmed a video course to build a real world project with Go.

4 Goimports
goimports is a command-line tool to automatically sort the imports of a source file : Here is an example of unsorted import declarations

//...
import (
"encoding/csv"
"fmt"
"log"
"math/rand"
"maximilien-andile.com/errors/application/generator"
"os"
"time"
)
//...

Here is the sorted version :

import (
"encoding/csv"
"fmt"
"log"
"math/rand"
"os"
"time"

"maximilien-andile.com/errors/application/generator"
)

4.1 Installation
Open a terminal and type the following command :

$ go get golang.org/x/tools/cmd/goimports

The binary will be installed here : $GOPATH/bin/goimports .

To make it available everywhere, make sure to add the folder $GOPATH/bin to your PATH

4.2 Usage
The command to use is :

$ goimports -w file.go

Where file.go is the file that you want to treat

3 of 9 02/01/2023, 02:25
Cheatsheet - Practical Go Lessons https://www.practical-go-lessons.com/chap-42-cheatsheet

5 Unit Tests
5.1 Test files
• Tests files are placed in the package directory

• They have the _test.go suffix

5.2 Test Function


Test functions are exported and have a specific name

Test function signature

5.3 Table Test


Here is an example table test :

func Test_totalPrice(t *testing.T) {


type parameters struct {
nights uint
rate uint
cityTax uint
}
type testCase struct {
name string
args parameters
want uint
}
tests := []testCase{
{
name: "test 0 nights",
args: parameters{nights: 0, rate: 150, cityTax: 12},
want: 0,
},
{
name: "test 1 nights",
args: parameters{nights: 1, rate: 100, cityTax: 12},
want: 112,
},
{
name: "test 2 nights",
args: parameters{nights: 2, rate: 100, cityTax: 12},
want: 224,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
time.Sleep(time.Second*1)
t.Parallel()
if got := totalPrice(tt.args.nights, tt.args.rate, tt.args.cityTax); got != tt.want {
t.Errorf("totalPrice() = %v, want %v", got, tt.want)
}
})
}
}

5.4 Commands
• Run all tests in a project

$ go test ./...

4 of 9 02/01/2023, 02:25
Cheatsheet - Practical Go Lessons https://www.practical-go-lessons.com/chap-42-cheatsheet

• Run tests of a specific package

◦ Into the package directory :

$ go test

◦ Outside the package directory :

$ go test modulepath/packagename

6 Naming Conventions
6.1 Module path
The module path is generally an URL pointing to a code-sharing website.

Ex : gitlab.com/loir402/bluesodium

The module path is written on the go.mod file :

module gitlab.com/loir402/bluesodium

go 1.15

Others will use the module path to import your module (if you have access to the repository) via, for instance, the go get command

go get gitlab.com/loir402/bluesodium

The last part of the URL should match the name of the principal package of your module (that will generally be placed at the root of the
project directory).

package main

import "gitlab.com/loir402/bluesodium"

func main() {
bluesodium.Color()
}

6.2 Package name


• short

• simple

• concise

• one word is better than two or more

7 The error interface


Here is the definition of the error interface (in the standard library) :

package builtin
//...
type error interface {
Error() string
}

Here is an example implementation of this interface :

5 of 9 02/01/2023, 02:25
Cheatsheet - Practical Go Lessons https://www.practical-go-lessons.com/chap-42-cheatsheet

// ReadingError is a custom type


type ReadingError struct {
}

// ReadingError implments error interface


func (e *ReadingError) Error() string {
return "error"
}

The paper and the digital edition of this book are available here. ×
I also filmed a video course to build a real world project with Go.

8 Type assertion
Here is the syntax of a type assertion.

x.(T)

• the value x has a type interface

T is a type. It might be a concrete type or a type interface.

8.1 When T is a concrete type


func doSomething() error {
//...
}

err := doSomething()

In this program, we define a function doSomething which returns an element of type interface error . We execute this function, and we
assign the return value to a new variable err .

We just know that err is of type interface error . We want to check that the dynamic type of err is *ReadingError . We can use a type
assertion :

// type assertion
v, ok := err.(*ReadingError)

if ok {
fmt.Println("err is of type *ReadingError")
}

err.(*ReadingError) returns two values :

• When err is of type *ReadingError . Assertion holds

v is of type *ReadingError

ok is equal to true2

• Otherwise

v is the zero value of the type *ReadingError . In this context, it’s equal to nil .

ok is equal to false3

8.1.1 T must implement the interface type of x!


The type assertion err.(*ReadingError) is legal in this context. The type *ReadingError implements the interface error and the value
err is of interface type error .

8.2 When T is an interface type


Let’s take an example with two interfaces Adder and Divider :

6 of 9 02/01/2023, 02:25
Cheatsheet - Practical Go Lessons https://www.practical-go-lessons.com/chap-42-cheatsheet

type Adder interface {


Add(a, b int) int
}

type Divider interface {


Divide(a, b int) float64
}

Then we define a new type MyAdder which implements Adder and Divider .

type MyAdder struct {


}

func (t *MyAdder) Add(a, b int) int {


return a + b
}
func (t *MyAdder) Divide(a, b int) float64 {
return float64(a / b)
}

The function foo returns an Adder interface type.

func foo() Adder {


return &MyAdder{}
}

Let’s check if the return value of foo also implements the Divider interface :

func main() {
x := foo()
if v, ok := x.(Divider); ok {
fmt.Println("x implements also interface Divider",v)
}
}

The syntax is identical. The type assertion will also check if x is not nil .

• When x implements Divider and is not nil :

v implements Divider

ok is equal to true

• Otherwise

v is equal to nil

ok is equal to false

8.3 A type assertion that may panic


When you use the syntax :

v, ok := x.(Divider)

your program will not panic if x is not of type Divider . Whereas the following syntax might cause a panic :

v := x.(Multiplier)
fmt.Printf("%v", v)

Here is the standard output :

7 of 9 02/01/2023, 02:25
Cheatsheet - Practical Go Lessons https://www.practical-go-lessons.com/chap-42-cheatsheet

panic: interface conversion: *main.MyAdder is not main.Multiplier: missing method Multiply

goroutine 1 [running]:
main.main()
/path/to/main.go:38 +0x100

Process finished with exit code 2

9 Environment variables
To check if an environment variable exists, you can use the os package :

port, found := os.LookupEnv("DB_PORT")


if !found {
log.Fatal("impossible to start up, DB_PORT env var is mandatory")
}

LookupEnv allows you to check if an env exists before using it.

10 Useful links
• The Go developer mailing list: https://groups.google.com/g/golang-dev

1. See https://github.com/golang/go/wiki/SliceTricks↩

2. It’s an untyped boolean value↩

3. It’s an untyped boolean value↩

Bibliography
• [minimal-version-cox] Cox, Russ. 2018. “Minimal Version Selection.” https://research.swtch.com/vgo-mvs.pdf.

Previous

Design Recommendations

Table of contents

Did you spot an error ? Want to give me feedback ? Here is the feedback page! ×

Newsletter:
Like what you read ? Subscribe to the newsletter.

I will keep you informed about the book updates.

@ [email protected]

Practical Go Lessons
By Maximilien Andile
Copyright (c) 2023
Follow me Contents
Posts
Book
Support the author Video Tutorial

About
The author
Legal Notice

8 of 9 02/01/2023, 02:25
Cheatsheet - Practical Go Lessons https://www.practical-go-lessons.com/chap-42-cheatsheet

Feedback
Buy paper or digital copy
Terms and Conditions

9 of 9 02/01/2023, 02:25

You might also like