Skip to content

Instantly share code, notes, and snippets.

@17twenty
Last active January 5, 2024 02:30
Show Gist options
  • Save 17twenty/03d101b1178f060e6bcf to your computer and use it in GitHub Desktop.
Save 17twenty/03d101b1178f060e6bcf to your computer and use it in GitHub Desktop.
17twenty / Nick's Golang Reading List

Getting Started with Go

Go Reading List

The following are a list of resources I find myself referring to:

These ones are more focused on cross-compiling and that sort of thing:

Installing Project dependencies

$ cd $GOPATH/src/proj
$ go get ./...

Project dependencies will be created under their own directories (namespaces) in $GOPATH/src

You should be able to test it works by running their respective testsuites:

$ go test -v proj
ok  	proj	0.012s

The flags for the Go tools everyone should know.

$ go build -x

-x lists all the commands go build invokes.

If you are curious about the Go toolchain, or using a cross-C compiler and wondering about flags passed to the external compiler, or suspicious about a linker bug; use -x to see all the invocations.

    $ go build -x
    WORK=/var/folders/00/1b8h8000h01000cxqpysvccm005d21/T/go-build600909754
    mkdir -p $WORK/hello/perf/_obj/
    mkdir -p $WORK/hello/perf/_obj/exe/
    cd /Users/jbd/src/hello/perf
    /Users/jbd/go/pkg/tool/darwin_amd64/compile -o $WORK/hello/perf.a -trimpath $WORK -p main -complete -buildid bbf8e880e7dd4114f42a7f57717f9ea5cc1dd18d -D _/Users/jbd/src/hello/perf -I $WORK -pack ./perf.go
    cd .
    /Users/jbd/go/pkg/tool/darwin_amd64/link -o $WORK/hello/perf/_obj/exe/a.out -L $WORK -extld=clang -buildmode=exe -buildid=bbf8e880e7dd4114f42a7f57717f9ea5cc1dd18d $WORK/hello/perf.a
    mv $WORK/hello/perf/_obj/exe/a.out perf

$ go build -gcflags

Used to pass flags to the Go compiler. go tool compile -help lists all the flags that can be passed to the compiler.

For example, to disable compiler optimizations and inlining, you can use the following the gcflags.

    $ go build -gcflags="-N -I"

$ go test -v

It provides chatty output for the testing. It prints the test name, its status (failed or passed), how much it took to run the test, any logs from the test case, etc.

go test without the -v flag is highly quiet, I always use it with -v turned on. Sample output:

    $ go test -v context
    === RUN   TestBackground
    --- PASS: TestBackground (0.00s)
    === RUN   TestTODO
    --- PASS: TestTODO (0.00s)
    === RUN   TestWithCancel
    --- PASS: TestWithCancel (0.10s)
    === RUN   TestParentFinishesChild
    --- PASS: TestParentFinishesChild (0.00s)
    === RUN   TestChildFinishesFirst
    --- PASS: TestChildFinishesFirst (0.00s)
    === RUN   TestDeadline
    --- PASS: TestDeadline (0.16s)
    === RUN   TestTimeout
    --- PASS: TestTimeout (0.16s)
    === RUN   TestCanceledTimeout
    --- PASS: TestCanceledTimeout (0.10s)
    ...
    PASS
    ok  	context	2.426s

$ go test -race

Go’s race detector is available from the Go tools via -race. go test also supports this flag and reports races. Use this flag during development to detect the races.

$ go test -run

You can filter tests to run by regex and the -run flag. The following command will only test examples.

$ go test -run=Example

$ go test -coverprofile

You can output a cover profile as you are testing a package, then use go tool to visualize them on a browser.

$ go test -coverprofile=c.out && go tool cover -html=c.out

The command above will create a coverage profile and open the results page in the browser.

$ go test -exec

It is a lesser known feature in Go that you can intercept the tools with another program by using the -exec flag. This flag allows you to delegate some work to an external program from the Go tool.

A commonly required scenario for this flag is when you need more than just executing the tests on the host machine. The Android builder for Go, uses -exec to push the test binaries to an Android device by using adb and collects the results. Android exec program can be used as a reference.

$ go get -u

If you run go-get for a package that is already in your GOPATH, go-get is not going to update the package to its latest version. -u forces the tool to sync with the latest version of the repo.

If you are a library author, you might like to write your installation instructions with a -u flag, e.g. the way golint does.

    $ go get -u github.com/golang/lint/golint

$ go get -d

If you just want to clone a repo to your GOPATH and skip the building and installation phase, use -d. It downloads the package and stops before trying to build or install it.

I often use it as a replacement for git clone for repos with vanity URLs, because it clones the repo to its proper GOPATH. For example,

    $ go get -d golang.org/x/oauth2/...

will clone the package to $GOPATH/src/golang.org/x/ouath2. Given golang.org/x/oauth2 is a vanity URL, go-getting the repo is useful rather than trying to figure out where the actual repo is (go.googlesource.com/oauth2).

$ go get -t

If your package has additional dependencies for tests, -t will allow you to download them during go-get. If you don’t pass -t, go get will only download the dependencies for your non-test code.

$ go list -f

Allows you to list Go packages with a custom format. It is highly useful for writing bash scripts.

The following command will print the dependencies of the runtime package:

    go list -f '{{.Deps}}' runtime
    [runtime/internal/atomic runtime/internal/sys unsafe]

More formatting ideas can be found at Dave Cheney’s article on go list.

Debugging What You Deploy (Go 1.12+)

https://blog.golang.org/debugging-what-you-deploy

High Performance / Tuning Your Golang

High Performance Go Workshop

Cross Compilation with CGo and Golang

Useful background: http://dave.cheney.net/2012/09/08/an-introduction-to-cross-compilation-with-go

@17twenty
Copy link
Author

Update your entire GOPATH

go get -v -d -u -f .../

@17twenty
Copy link
Author

17twenty commented Dec 9, 2016

func withLockContext(fn func()) {
    mu.Lock
    defer mu.Unlock()

    fn()
}
....
withLockContext(func() {
    // Locky related stuff
})

@17twenty
Copy link
Author

17twenty commented Jan 13, 2017

How To Close Channels in Golang Elegantly

package main

import "fmt"

type T int

func IsClosed(ch <-chan T) bool {
	select {
	case <-ch:
		return true
	default:
	}
	
	return false
}

func main() {
	c := make(chan T)
	fmt.Println(IsClosed(c)) // false
	close(c)
	fmt.Println(IsClosed(c)) // true
}

See also, the Channel Axioms guide

@17twenty
Copy link
Author

Building totally static binaries:

$ go build -a --ldflags '-extldflags "-static"' -tags netgo -installsuffix netgo  .

@17twenty
Copy link
Author

17twenty commented Feb 20, 2017

Embedding Build Time Variables

Quite a useful technique for reproducible builds or stuff like that - let's say you have this source file saved as hello.go:

package main

import "fmt"

var (
    who = "World"
)

func main() {  
    fmt.Println("Hello,", who)
}

Then you can use go run (or other build commands like go build or go install) with the -ldflags option to modify the value of the who variable:

$ go run hello.go
Hello, World.  
$ go run -ldflags="-X main.who=Nick" hello.go
Hello, Nick

The format is importpath.name string, so you can set the value of any string in your program, not just in main.

@17twenty
Copy link
Author

17twenty commented Aug 2, 2017

@17twenty
Copy link
Author

Using the DAO / Repo pattern for Golang - https://adodd.net/post/go-ddd-repository-pattern/

@17twenty
Copy link
Author

17twenty commented Sep 30, 2021

Log

https://play.golang.org/p/8jtyDzQZZ3h ... but ideally use uber/zip or similar.

Testing Code Effectively with Go

  1. Test what matters
  2. Test the right level
  3. Mock but dont be silly
  4. func fields make testing easier (see Safety culture article on better mocking)
  5. test failures point to the problems.

Better mocking
https://medium.com/safetycultureengineering/flexible-mocking-for-testing-in-go-f952869e34f5

How to test / The art of testing
https://www.youtube.com/watch?v=EOpj9aZ8Kfo
Slides

Good tests dont mock databases
https://qvault.io/clean-code/writing-good-unit-tests-dont-mock-database-connections/

What not to use
https://www.youtube.com/watch?v=5DVV36uqQ4E

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment