Moving to Go - What I Wish I'd Known

Quite a few people I know are expressing interest in learning Go, so I decided to put down a couple of notes about my experience after having had the same conversation a few times over. None of the points are particularly original and are mostly here so I can point people at one place when they ask me about it! Your mileage may vary on any of this stuff and it’s in no particular order!

Note: this is old content, but since I still get emails about it, it seems it is useful to people and therefore worth leaving online! Buyer beware however - it has not been updated since 2015.

Go By Example

Go By Example is a great learning resource for the fundamentals of the language. After that the posts on Gopher Acadamy are well worth reading. I’m not aware of any good print books right now, though I’m sure they exist.

Update (2-Feb-2015): Also on the reading list after Go By Example is Effective Go, which goes a long way towards documenting how to write idiomatic Go.

Test scripts using Go Run

go run is awesome - you could almost use it as a scripting language and it’s invaluable for quickly testing snippets of code. Not quite a REPL, but it works for me.

Don’t fight the $GOPATH

Don’t fight the $GOPATH. This one is hard as for years I’ve had code organized under ~/Code/repo_name, and the immediate instinct is to keep things structured in the same way. Whilst the documentation is (or was at least) somewhat ambiguous about this, the intended method for working with Go code is to have a single $GOPATH across projects.

My $GOPATH is set to ~/Code/go, and I have the following zsh functions defined to make it easy to move around between different projects:

cg() {
    cd $GOPATH/src/$1;

And the autocomplete for cg:

#compdef cg
_files -W $GOPATH/src/ -/

This means that I can move around projects like this (since basically all important code lives on GitHub, except for the standard library):

$ cg jen20/terraform-provider-azure && pwd

$ cg MSOpenTech/azure-sdk-for-go && pwd


Use vim-go. Initially I tried using the IntelliJ plugin for Go, as a long time IntelliJ and Resharper user I still find the autocompletion to be invaluable when navigating unfamiliar libraries. However, when I tried it the IntelliJ plugin didn’t work with the single $GOPATH detailed above.

There’s a nice guide to setting up vim-go here. There are still a few niggles to fix with it (finding documentation is somewhat hit and miss from time to time). Turning on the type annotations for the identifier under the cursor is invaluable.

The only customizations I have for the vim-go plugin in my .vimrc are as follows:

let g:go_fmt_fail_silently = 1
let g:go_fmt_command = "gofmt"
let g:go_auto_type_info = 1

" Specific file types
augroup filetypedetect_go
    autocmd FileType go nmap gd <Plug>(go-def)
    autocmd FileType go nmap <Leader>s <Plug>(go-def-split)
    autocmd FileType go nmap <Leader>v <Plug>(go-def-vertical)
    autocmd FileType go nmap <Leader>t <Plug>(go-def-tab)

    autocmd FileType go nmap <Leader>i <Plug>(go-info)

    autocmd FileType go nmap <leader>r <Plug>(go-run)
    autocmd FileType go nmap <leader>b <Plug>(go-build)

    autocmd FileType go nmap <Leader>d <Plug>(go-doc)
augroup END


Use Dash on OS X. One thing to be said for Visual Studio (when appropriately extended with ReSharper) is that you rarely have to leave it. The Intellisense docs mean that it’s rarely necessary to go and read the documentation. With Go the docs are excellent, but are made even better with Dash. It’s one of the best uses for £13 and works across all languages. You can install it via brew cask for added awesome.

Update (2-Feb-2015): People have pointed out Zeal, which is similar to Dash for Linux and Windows, and also which is a browser based version with an offline mode.

Dependency Management

Don’t be tempted to try to replicate complex dependency management tools such as npm or (god forbid) NuGet. Instead prefer to take fewer dependencies. This is made easier by an excellent standard library which covers a very wide range of things very comprehensively.

Most libraries are small (one or two files) and can be copied and pasted into your own source tree, license permitting . GoDep appears to be the only thing approaching an officially sanctioned way, and has a nice mode which vendors libraries into your own source tree and rewrites the imports.

Use standard tools like Make

Write Makefiles for anything that isn’t a one step go build, and consider it even when that’s the only build step. There are very well known arguments for using Make over other tools. This one isn’t specific to Go though - most of my .NET projects build using Make as well these days.