```sh
brew install go
brew install golangci-lint
brew install gopls
go install golang.org/x/tools/cmd/godoc@latest
```
# Statements
- Modules of the Golang testing package
- [[The Golang install command can be used to install godoc]]
- [[Go is easier for someone who has chunked computer science]]
# About
[Learn Go in Y Minutes - Go](https://learnxinyminutes.com/docs/go/) and [Go documentation — DevDocs](https://devdocs.io/go/).
[[Learn Go with tests]].
Go is a fast, [[Statically typed]], [[Compiled language]]. It is also a strongly typed language - see [[Strong and weak typing]].
I've worked with [Cobra](https://github.com/spf13/cobra) + [Viper](https://github.com/spf13/viper) for creating [[Command line interface]]s. Made a small tool for reconciling a Oracle database with a [[PostgreSQL]] DB (using [[Set theory]]). The project was a bit of an [[Anti-pattern]] that I didn't really condone. I added [zap](https://github.com/uber-go/zap) for [[Structured logging]] just for fun.
I have recreated [Marklink](https://github.com/staticaland/marklink) in Golang, but didn't finish up yet. It's noticably faster.
I watched [a guy with a flat cap teach about Golang](https://learning.oreilly.com/videos/ultimate-go-programming/9780135261651/) on [[O'Reilly]].
## Learning resources
[The Net Ninja](https://www.youtube.com/watch?v=etSN4X_fCnM&list=PL4cUxeGkcC9gC88BEo9czgyS72A3doDeM) got a nice course for beginners.
[The Go Programming Language](https://learning.oreilly.com/library/view/the-go-programming/9780134190570/) is a well regarded book. It has a lot of useful examples. [Let's Go! A start-to-finish guide to building web apps with Go](https://lets-go.alexedwards.net/) has been recommended by many. It precedes [Let's Go Further! Advanced patterns for APIs and web applications in Go](https://lets-go-further.alexedwards.net/):
> As well as covering fundamental topics like sending and receiving JSON data, the book goes in-depth and explores practical code patterns and best practices for _advanced functionality_ like implementing graceful shutdowns, managing background tasks, reporting metrics, and much more.
## Structs
Go's structs are typed collections of fields. They're useful for grouping data together to form records. Structs are mutable. Reminds me of [[Associative array]].
```go
type person struct {
name string
age int
}
```
You can make a list of `person` structs and loop through them using [[Range (Golang)]]:
```go
var persons = []person {
person {
name: 'anders',
age: 31
},
person {
name: 'ninja',
age: 22
},
}
for _, person := range persons {
fmt.Printf("%s\n", person.name)
}
```
Range returns the index (ie. 0, 1, 2) and the actual element. It works the same as `enumerate(persons)` in [[Python]] (what I am doing here is called [[Chunking]] or [[Aliasing]] - [Let the knife do the work](https://www.youtube.com/watch?v=bTee6dKpDB0)).
Learn more at [How do I iterate over an array of a custom type in Go?](https://stackoverflow.com/questions/48693172/how-do-i-iterate-over-an-array-of-a-custom-type-in-go) and [Go by Example: Range](https://gobyexample.com/range).
## Maps
I will write some notes about maps.
[Go by Example: Maps](https://gobyexample.com/maps).
## Python equivalents
[Go for Python Programmers](https://golang-for-python-programmers.readthedocs.io/en/latest/) talks about some [[Python]] equivalents to Go. I did not find it very useful.
## For loops
```go
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
```
The basic `for` loop has **three components** separated by semicolons:
- the init statement: executed before the first iteration
- `for i := 0;`
- the condition expression: evaluated before every iteration
- `i > 10`
- the post statement: executed at the end of every iteration
- `i++`
Another useful example from [[The Go Programming Language]]:
```go
var a [3]int // array of 3 integers
fmt.Println(a[0]) // print the first element
fmt.Println(a[len(a)-1]) // print the last element, a[2]
// Print the indices and elements.
for i, v := range a {
fmt.Printf("%d %d\n", i, v)
}
// Print the elements only.
for _, v := range a {
fmt.Printf("%d\n", v)
}
```
## Pointers
Go has pointers. A pointer holds the [[Memory address]] of a value. Maybe watch [CS50 2020 - Lecture 4 - Memory](https://www.youtube.com/watch?v=NKTfNv2T0FE) by [[David J. Malan]] if you want to learn more about memory addresses.
Why would you want to use a pointer? They are used for efficiency. Go does not help you do stuff efficiently. You have full control yourself. No optimizations (kinda).
[When to use pointers in Go](https://medium.com/@meeusdylan/when-to-use-pointers-in-go-44c15fe04eac):
> **Passing pointers in Go is often slower than passing values**. This is a result of Go being a garbage collected language. When you pass a pointer to a function, Go needs to perform Escape Analysis to figure out if the variable should be stored on the heap or the stack. This already adds a bit of overhead, but in addition the variable could be stored on the heap. When you store a variable on the heap, you also lose time when the GC is running.
### The operators of pointers in C
`&` is the "address of" operator. What address is this variable stored at?
`*` means to look inside of a memory address. It's called the dereference operator. It dereferences an address.
Consider the following:
```c
#include <stdio.h>
int main(void)
{
int n = 50;
printf("%i\n", n);
printf("%p\n", &n);
printf("%i\n", *&n);
}
```
It gives us something like:
```c
50
0x7ffc68014484
50
````
Let's try to use a pointer by doing `int *p = &n` - an address of an int.
```c
#include <stdio.h>
int main(void)
{
int n = 50;
int *p = &n;
printf("%p\n", p);
}
```
How do you print out the value of `n` through the pointer? Which operator lets us look into a memory address?
```c
printf("%i\n", *p);
```
A pointer is useful because a string is an array of bytes that always ends with `\0`. This means you only have to know where the array begins and move up until you find the `\0`. Pointers tend to take up 8 bytes in memory.
### The operators of pointers in Go
`&` generates a pointer to the variable.
`*` means to look inside of a memory address. It's called the dereference operator. It dereferences an address.
```go
package main
import "fmt"
func main() {
n := 42
p := &n
fmt.Println(p)
}
```
```
0xc0000bc000
```
## Instrumenting a Go application for Prometheus
[Instrumenting a Go application](https://prometheus.io/docs/guides/go-application/) for [[Prometheus]] is the place to start. It has a few simple examples. It's easy to get going.
## People
[[Kavya Joshi]]