Go
Installing
Always remove previous versions before installing newer ones.
Manually
Officially, Go docs tells to manually download the latest version and install it.
wget https://go.dev/dl/go1.xx.x.linux-amd64.tar.gz
sudo rm -rf /opt/go && sudo tar -C /opt -xzf go1.*.linux-amd64.tar.gzAdd this env to .bashrc.
export PATH=$PATH:/usr/local/go/binVersion manager
There is a version manager kind of like python pyenv.
It automatically adds the Path variables to .bashrc and installs the latest Go version.
wget -qO- https://git.io/g-install | sh -sOther commands:
# Download and set version to latest
g install latest
# Download and set to <version>
g install <version>
# List installed versions
g list
# List all versions
g list-all
# Remove all versions, except the current used one
g pruneRun & Compile
Run uncompiled
Run an uncompiled file.go file with:
go run file.goCompile
To build and generate an executable the project needs a Modules.
go buildRun compiled
In Windows the compiled will be a .exe file, whether in Linux or Mac it will be a executable file.
Memory Management
Go automatically manages memory with its Garbage Collector.
Most of variables allocation definition is done at compile time. But they can be moved in certain circunstances at runtime.
Check escape analysis and heap allocation by running go build -gcflags '-m'.
Tips for better performance
Don't always use pointers in parameters to pass values like structs, to avoid memory duplication. (Target pointers to > 64 bytes structs, or if used in multiple functions)
Prefer Stack allocation when possible.
Stack
Used for small, local, short-lived, and that do not escape the function variables.
Automatically cleaned up when function exits. (That's why short-lived)
Variables allocated in the Stack, can be moved at runtime to the heap if they escape their initial scope.
They will be in the Stack or stay there if no conditions to go to the Heap are met.
Heap
Used for large or long-lived variables (slower, garbage-collected)
They live until garbage collected. (That's why long-lived)
A closure captures a variable
func() { x++ }
The variable outlives the function
Returning a pointer to a local variable
return &x
The local variable must persist
Structs stored in an interface
var i interface{} = MyStruct{}
Interfaces store references
Large arrays/slices (Maps always)
make([]int, 100000)
Avoids stack overflow
Structs passed by reference
func test(p *Person){}
Explicit heap allocation
General rules for Arrays/Maps/Slices
Slices themselves (the slice header: pointer, length, capacity) is allocated in the Stack.
But its underlying Array is in the Heap IF they are large.
Maps are always allocated in the Heap, because internally, it contains a pointer to a hash table, which lives in the heap.
Memory Leaks
Monitor memory leaks using pprof (Go's profiling tool)
Usually happen when Heap memory isn't freed properly.
Global variables holding large data
Avoid unnecessary global variables
Unclosed Goroutines
Use sync.WaitGroup or context.Context to stop them
Slices growing without limit
Use make() with a sensible capacity
Forgotten closures holding memory
Set function references to nil when no longer needed
Last updated