Stupid Gopher Tricks
GolangUK
21 Aug 2015

Andrew Gerrand
adg@golang.org

* This talk

This talk is about things you might not know about Go.

Some of this stuff you can add to your Go vocabulary.

Other things are probably best left for special occasions.


* Language


* Type literals (1/2)

Here's a familiar type declaration:

	type Foo struct {
		i int
		s string
	}

The latter part of a type declaration is the *type*literal*:

	struct {
		i int
		s string
	}

Other examples of type literals are `int` and `[]string`,
which can also be declared as named types:

	type Bar int
	type Qux []string


* Type literals (2/2)

While we commonly use `int` and `[]string` in variable declarations:

	var i int
	var s []string

It is less common (but equally valid) to do the same with structs:

	var t struct {
		i int
		s string
	}

An unnamed struct literal is often called an *anonymous*struct*.


* Anonymous structs: template data

A common use is providing data to templates:

.play tricks/template.go /BEGIN/,/END/

You could also use `map[string]interface{}`,
but then you sacrifice performance and type safety.


* Anonymous structs: JSON (1/2)

The same technique can be used for encoding JSON objects:

.play tricks/json-encode.go /Marshal/,/Print/

And also decoding:

.play tricks/json-decode.go /data/,/Print/


* Anonymous structs: JSON (2/2)

Structs can be nested to describe more complex JSON objects:

.play tricks/json-nest.go /data/,/Print/


* Repeated literals and struct names

In repeated literals like slices and maps, Go lets you omit the inner type name:

.code tricks/repeated.go /BEGIN/,/END/


* Repeated literals and anonymous structs

Combined with anonymous structs, this convenience shortens the code dramatically:

.code tricks/repeated2.go /BEGIN/,/END/


* Anonymous structs: test cases (1/2)

These properties enable a nice way to express test cases:

.code tricks/string_test.go /TestIndex/,/^}/


* Anonymous structs: test cases (2/2)

You can go a step further and put the composite literal in the range statement itself:

.code tricks/string_test2.go /TestIndex/,/^}/

But this is harder to read.


* Embedded fields

A struct field that has no name is an *embedded*field*.
The embedded type's methods (and fields, if it is a struct)
are accessible as if they are part of the embedding struct.

.play tricks/embed.go /BEGIN/,$


* Anonymous structs: embedded mutex

Of course, you can embed fields in an anonymous struct.

It's common to protect a global variable with a mutex variable:

	var (
		viewCount   int64
		viewCountMu sync.Mutex
	)

By embedding a mutex in an anonymous struct, we can group the related values:

	var viewCount struct {
		sync.Mutex
		n int64
	}

Users of `viewCount` access it like this:

	viewCount.Lock()
	viewCount.n++
	viewCount.Unlock()



* Anonymous structs: implementing interfaces

And you can embed interfaces, too.

Here's a real example from [[https://camlistore.org/][Camlistore]]:

The function is expected to return a `ReadSeekCloser`,
but the programmer only had a string.

Anonymous struct (and its standard library friends) to the rescue!

	return struct {
		io.ReadSeeker
		io.Closer
	}{
		io.NewSectionReader(strings.NewReader(s), 0, int64(len(s))),
		ioutil.NopCloser(nil),
	}


* Anonymous interfaces

Interfaces can be anonymous, the most common being `interface{}`.

But the interface needn't be empty:

.play tricks/anon-interface.go /var s/,/Println/

Useful for a sly type assertion (from `src/os/exec/exec_test.go`):

	// Check that we can access methods of the underlying os.File.
	if _, ok := stdin.(interface {
		Fd() uintptr
	}); !ok {
		t.Error("can't access methods of underlying *os.File")
	}


* Method values

A "method value" is what you get when you evaluate a method as an expression.
The result is a function value.

Evaluating a method from a _type_ yields a function:

.play tricks/method-values-1.go /var f/,/Stdout/

Evaluating a method from a _value_ creates a closure that holds that value:

.play tricks/method-values-2.go /var /,/Stdout/


* Method values: sync.Once

The `sync.Once` type is used to perform a task once with concurrency safety.

	// Once is an object that will perform exactly one action.
	type Once struct { /* Has unexported fields. */ }

	func (o *Once) Do(f func())
	
This `LazyPrimes` type computes a slice of prime numbers the first time it is used:

.code tricks/method-once.go /type/,$


* Method values: HTTP handlers

You can use method values to implement multiple HTTP handlers with one type:

.code tricks/method-http.go /type Server/,$


* Method values: another example

In package `os/exec`, the `Cmd` type implements methods to set up
standard input, output, and error:

	func (c *Cmd) stdin() (f *os.File, err error)
	func (c *Cmd) stdout() (f *os.File, err error)
	func (c *Cmd) stderr() (f *os.File, err error)

The caller handles each in the same way,
so it iterates over a slice of method values:

	type F func(*Cmd) (*os.File, error)
	for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} {
		fd, err := setupFd(c)
		if err != nil {
			c.closeDescriptors(c.closeAfterStart)
			c.closeDescriptors(c.closeAfterWait)
			return err
		}
		c.childFiles = append(c.childFiles, fd)
	}


* Comparable types

The Go spec defines a set of types as "comparable";
they may be compared with == and !=.

Bools, ints, floats, complex numbers, strings, pointers,
channels, *structs*, and *interfaces* are comparable.

.play tricks/compare.go /BEGIN/,/END/

A struct is comparable only if its fields are comparable:

.play tricks/compare2.go /BEGIN/,/END/


* Comparable types and map keys

Any comparable type may be used as a map key.

.code tricks/compare-map.go /BEGIN/,/END/


* Structs as map keys

An example from the Go continuous build infrastructure:

	type builderRev struct {
		builder, rev string
	}

	var br = builderRev{"linux-amd64", "0cd299"}

We track in-flight builds in a map.
The pre-Go 1 way was to flatten the data to a string first:

	inflight := map[string]bool{}

	inflight[br.builder + "-" + br.rev] = true

But with struct keys, you can avoid the allocation and have cleaner code:

	inflight := map[builderRev]bool{}

	inflight[br] = true


* Interfaces as map keys

An example of interface map keys from Docker's `broadcastwriter` package:

.code tricks/broadcastwriter/broadcastwriter.go /type/,/END/


* Structs and interfaces together as map keys

A (very) contrived example: (Don't do this! Ever!)

.play tricks/cons.go /type/,$


* Libraries

* sync/atomic

For a simple counter, you can use the `sync/atomic` package's
functions to make atomic updates without the lock.

	func AddInt64(addr *int64, delta int64) (new int64)
	func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
	func LoadInt64(addr *int64) (val int64)
	func StoreInt64(addr *int64, val int64)
	func SwapInt64(addr *int64, new int64) (old int64)

First, define the global variable (appropriately documented!):

	// viewCount must be updated atomically.
	var viewCount int64

Then increment it with `AddInt64`:

	count := atomic.AddInt64(&viewCount, 1)

The set are available for `Int32`, `Uint32`, `Int64`, `Uint64`, `Pointer`, and `Uintptr`.


* sync/atomic.Value

Another option for sharing state is `atomic.Value`.

For instance, to share configuration between many goroutines:

	type Config struct {
		Timeout time.Duration
	}

	var config atomic.Value

To set or update, use the `Store` method:
	
	config.Store(&Config{Timeout: 2*time.Second})

To read, each goroutine calls the `Load` method:

	cfg := config.Load().(*Config)

Note that storing different types in the same `Value` will cause a panic.


* sync/atomic.Value: how it works (1/5)

The `atomic.Value` primitive is the size of a single interface value:

	package atomic

	type Value struct {
		v interface{}
	}

An interface value is represented by the runtime as two pointers:
one for the type, and one for the value.

	// ifaceWords is interface{} internal representation.
	type ifaceWords struct {
		typ  unsafe.Pointer
		data unsafe.Pointer
	}

To load and store an interface value atomically, it operates on the parts of the interface value with `atomic.LoadPointer` and `atomic.StorePointer`.


* sync/atomic.Value: how it works (2/5)

The `Store` method first validates the input:

	func (v *Value) Store(x interface{}) {
		if x == nil {
			panic("sync/atomic: store of nil value into Value")
		}

Then uses `unsafe` to cast the current and new `interface{}` values to `ifaceWords`:

	// ...
		vp := (*ifaceWords)(unsafe.Pointer(v))
		xp := (*ifaceWords)(unsafe.Pointer(&x))

(This allows us to get at the internals of those interface values.)


* sync/atomic.Value: how it works (3/5)

Spin while loading the type field:

	// ...
		for {
			typ := LoadPointer(&vp.typ)

If it's `nil` the this is the first time the value has been stored.
Put a sentinel value (max uintptr) in the type field to "lock" it while we work with it:

	// ...
			if typ == nil {
				if !CompareAndSwapPointer(&vp.typ, nil, unsafe.Pointer(^uintptr(0))) {
					continue // Someone beat us to it. Wait.
				}

Store the data field, then the type field, and we're done!

	// ...
				StorePointer(&vp.data, xp.data)
				StorePointer(&vp.typ, xp.typ)
				return
			}

* sync/atomic.Value: how it works (4/5)

If this isn't the first store, check whether a store is already happening:

	// ...
			if uintptr(typ) == ^uintptr(0) {
				continue // First store in progress. Wait.
			}

Sanity check whether the type changed:

	// ...
			if typ != xp.typ {
				panic("sync/atomic: store of inconsistently typed value into Value")
			}

If the type field is what we expect, go ahead and atomically store the value:

	// ...
			StorePointer(&vp.data, xp.data)
			return
		}
	}

* sync/atomic.Value: how it works (5/5)

The `Load` method first loads the interface's type field:

	func (v *Value) Load() (x interface{}) {
		vp := (*ifaceWords)(unsafe.Pointer(v))
		typ := LoadPointer(&vp.typ)

Then, check whether a store has happened, or is happening:

	// ...
		if typ == nil || uintptr(typ) == ^uintptr(0) {
			return nil
		}

Otherwise, load the data field and return both type and data as a new interface value:

	// ...
		data := LoadPointer(&vp.data)
		xp := (*ifaceWords)(unsafe.Pointer(&x))
		xp.typ = typ
		xp.data = data
		return
	}


* A note on sync/atomic

Usually you don't want or need the stuff in this package.

Try channels or the `sync` package first.

You almost certainly shouldn't write code like the `atomic.Value` implementation.
(And I didn't show all of it; the real code has hooks into the runtime.)


* Tools


* Testing

* Subprocess tests

Sometimes you need to test the behavior of a process, not just a function.

.code tricks/subprocess/subprocess.go /func Crasher/,/^}/

To test this code, we invoke the test binary itself as a subprocess:

.code tricks/subprocess/subprocess_test.go /func TestCrasher/,/^}/


* Subprocess benchmarks (1/2)

Go's CPU and memory profilers report data for an entire process.
To profile just one side of a concurrent operation, you can use a sub-process.

This benchmark from the `net/http` package spawns a child process to make
requests to a server running in the main process.

	func BenchmarkServer(b *testing.B) {
		b.ReportAllocs()
		// Child process mode;
		if url := os.Getenv("TEST_BENCH_SERVER_URL"); url != "" {
			n, err := strconv.Atoi(os.Getenv("TEST_BENCH_CLIENT_N"))
			if err != nil {
				panic(err)
			}
			for i := 0; i < n; i++ {
				res, err := Get(url)
				// ...
			}
			os.Exit(0)
			return
		}
	// ...

* Subprocess benchmarks (2/2)

	// ...
		res := []byte("Hello world.\n")
		ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
			rw.Header().Set("Content-Type", "text/html; charset=utf-8")
			rw.Write(res)
		}))
		defer ts.Close()

		cmd := exec.Command(os.Args[0], "-test.run=XXXX", "-test.bench=BenchmarkServer$")
		cmd.Env = append([]string{
			fmt.Sprintf("TEST_BENCH_CLIENT_N=%d", b.N),
			fmt.Sprintf("TEST_BENCH_SERVER_URL=%s", ts.URL),
		}, os.Environ()...)
		if out, err := cmd.CombinedOutput(); err != nil {
			b.Errorf("Test failure: %v, with output: %s", err, out)
		}
	}

To run:

	$ go test -run=XX -bench=BenchmarkServer -benchtime=15s -cpuprofile=http.prof
	$ go tool pprof http.test http.prof


* go list

* go list

	$ go help list
	usage: go list [-e] [-f format] [-json] [build flags] [packages]

	List lists the packages named by the import paths, one per line.

Show the packages under a path:

	$ go list golang.org/x/oauth2/...
	golang.org/x/oauth2
	...
	golang.org/x/oauth2/vk

Show the standard library:

	$ go list std
	archive/tar
	...
	unsafe

Show all packages:

	$ go list all

* go list -json

The `-json` flag tells you everything the go tool knows about a package:

	$ go list -json bytes
	{
		"Dir": "/Users/adg/go/src/bytes",
		"ImportPath": "bytes",
		"Name": "bytes",
		"Doc": "Package bytes implements functions for the manipulation of byte slices.",
		"Target": "/Users/adg/go/pkg/darwin_amd64/bytes.a",
		"Goroot": true,
		"Standard": true,
		"Stale": true,
		"Root": "/Users/adg/go",
		"GoFiles": [
			"buffer.go",
			"bytes.go",
			"bytes_decl.go",
			"reader.go"
		],
		...
	}

It's easy to write programs that consume this data.

* go list's Package struct (1/3)

The go tool's documented `Package` struct describes all the possible fields:

	type Package struct {
		Dir           string // directory containing package sources
		ImportPath    string // import path of package in dir
		ImportComment string // path in import comment on package statement
		Name          string // package name
		Doc           string // package documentation string
		Target        string // install path
		Shlib         string // the shared library that contains this package (only set when -linkshared)
		Goroot        bool   // is this package in the Go root?
		Standard      bool   // is this package part of the standard Go library?
		Stale         bool   // would 'go install' do anything for this package?
		Root          string // Go root or Go path dir containing this package

		// (more fields on next slide)
	}

* go list's Package struct (2/3)

	type Package struct {
		// (more fields on previous slide)

		// Source files
		GoFiles        []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
		CgoFiles       []string // .go sources files that import "C"
		IgnoredGoFiles []string // .go sources ignored due to build constraints
		CFiles         []string // .c source files
		CXXFiles       []string // .cc, .cxx and .cpp source files
		MFiles         []string // .m source files
		HFiles         []string // .h, .hh, .hpp and .hxx source files
		SFiles         []string // .s source files
		SwigFiles      []string // .swig files
		SwigCXXFiles   []string // .swigcxx files
		SysoFiles      []string // .syso object files to add to archive

		// (more fields on next slide)
	}

* go list's Package struct (3/3)

	type Package struct {
		// (more fields on previous slide)

		// Cgo directives
		CgoCFLAGS    []string // cgo: flags for C compiler
		CgoCPPFLAGS  []string // cgo: flags for C preprocessor
		CgoCXXFLAGS  []string // cgo: flags for C++ compiler
		CgoLDFLAGS   []string // cgo: flags for linker
		CgoPkgConfig []string // cgo: pkg-config names

		// Dependency information
		Imports []string // import paths used by this package
		Deps    []string // all (recursively) imported dependencies

		// Error information
		Incomplete bool            // this package or a dependency has an error
		Error      *PackageError   // error loading package
		DepsErrors []*PackageError // errors loading dependencies

		TestGoFiles  []string // _test.go files in package
		TestImports  []string // imports from TestGoFiles
		XTestGoFiles []string // _test.go files outside package
		XTestImports []string // imports from XTestGoFiles
	}

* go list -f (1/2)

That's a ton of information, so what can we do with it?

The `-f` flag lets you use Go's `text/template` package to format the ouput.

Show package doc strings:

	$ go list -f '{{.Doc}}' golang.org/x/oauth2/...
	Package oauth2 provides support for making OAuth2 authorized and authenticated HTTP requests.
	Package jwt implements the OAuth 2.0 JSON Web Token flow, commonly known as "two-legged OAuth 2.0".
	...

Show the Go files in a package:

	$ go list -f '{{.GoFiles}}' bytes
	[buffer.go bytes.go bytes_decl.go reader.go]

Make the output cleaner with a `join`:

	$ go list -f '{{join .GoFiles " "}}' bytes
	buffer.go bytes.go bytes_decl.go reader.go 

* go list -f (2/2)

With template logic we can test packages for certain conditions.

Find standard libraries that lack documentation:

	$ go list -f '{{if not .Doc}}{{.ImportPath}}{{end}}' std
	internal/format
	internal/trace

Find packages that depend (directly or indirectly) on a given package:

	$ go list -f '{{range .Deps}}{{if eq . "golang.org/x/oauth2"}}{{$.ImportPath}}{{end}}{{end}}' all
	golang.org/x/build/auth
	golang.org/x/build/buildlet
	golang.org/x/build/cmd/buildlet
	...

Find packages that are broken somehow (note `-e`):

	$ go list -e -f '{{with .Error}}{{.}}{{end}}' all
	package github.com/golang/oauth2: code in directory /Users/adg/src/github.com/golang/oauth2
		expects import "golang.org/x/oauth2"
	...

* go list and the shell

Things get interesting once we start using the shell.

For instance, we can use `go` `list` output as input to the go tool.

Test all packages except vendored packages:

	$ go test $(go list ./... | grep -v '/vendor/')

Test the dependencies of a specific package:

	$ go test $(go list -f '{{join .Deps " "}}' golang.org/x/oauth2)

The same, but don't test the standard library:

	$ go test $(
		go list -f '{{if (not .Goroot)}}{{.ImportPath}}{{end}}' $(
			go list -f '{{join .Deps " "}}' golang.org/x/oauth2
		)
	)

* go list printing line counts

	for pkg in $(go list golang.org/x/oauth2/...); do
		wc -l $(go list -f '{{range .GoFiles}}{{$.Dir}}/{{.}} {{end}}' $pkg) | \
			tail -1 | awk '{ print $1 " '$pkg'" }'
	done | sort -nr

The output:

	617 golang.org/x/oauth2/google
	600 golang.org/x/oauth2
	357 golang.org/x/oauth2/internal
	160 golang.org/x/oauth2/jws
	147 golang.org/x/oauth2/jwt
	112 golang.org/x/oauth2/clientcredentials
	22 golang.org/x/oauth2/paypal
	16 golang.org/x/oauth2/vk
	16 golang.org/x/oauth2/odnoklassniki
	16 golang.org/x/oauth2/linkedin
	16 golang.org/x/oauth2/github
	16 golang.org/x/oauth2/facebook

* go list generating dependency graphs

	(   echo "digraph G {"
		go list -f '{{range .Imports}}{{printf "\t%q -> %q;\n" $.ImportPath .}}{{end}}' \
			$(go list -f '{{join .Deps " "}}' time) time
		echo "}"
	) | dot -Tsvg -o time-deps.svg

.image tricks/time-deps.png 400 _


* And there's more!

There are many more fun corners of Go.
Can you find them all? :-)

Read the docs, explore, and have fun!
