```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]]