Skip to content

Latest commit

 

History

History
72 lines (51 loc) · 2.05 KB

File metadata and controls

72 lines (51 loc) · 2.05 KB

Go refresher

Starting a new project:

  • put main.go in the root folder
  • go mod init rootfoldername
  • go run . to run
  • Code:
package main
import "fmt"
func main() {
    fmt.Println("Hello, World!")
}

Adding a dependency

  • go get github.com/rivo/tview@master
  • Files dumped in $GOPATH/pkg/mod, which is usually ~/.go/pkg/mod
  • Verify location with go env GOMODCACHE
  • Reference the dependency in the code, eg: import "foo/bar"
  • go mod tidy to remove anything no longer used.

Standard project layouts

Go file layouts are a bit unusual. Do like this:

- cmd/cmdname/main.go if a multi-executable project
- main.go if just a single executable project
  • go.mod is the list of modules your code uses, along with the versions
  • go.sum is the hashes of the modules, so your code is replicable on another machine.

Compiling an executable

go build -o exe-name

Understanding code

Years ago when I worked in Go, several idioms were mysteries that I used without really understanding them and I disliked Go because there was very little documentation at the time. Now with AI to query, the language is more enjoyable because there are fewer footguns to trip me up. Notable examples below..

selected: make(map[int]struct{})

map[int]struct{} - map creates a map (dictionary). They keys are ints and the values are struct{}s. struct{} is a 0-byte memory structure in Go. So this is a way to create a mapping that has keys but no values. The Go compiler essentially optimizes this down to a set.

You would store values in this map like m.mymap[2] = struct{}{}. Even though it appears as though you are storing something in the map, no value is stored, just the key.

switch msg := msg.(type) {}

msg.(type) here is referred to as a Type switch. It runs the switch statement on the type of the thing (the msg). So msg can be any type at runtime. In practice, msg must be an empty interface like interface{} that doesn't become a thing until called. x.(type) is only valid inside a switch statement. This is a workaround to handle dynamic types.