I've been coding in Go everyday for the past 3 months, for Summit Route. This post describes how I use Go and what works for me, some of which differs from what I've seen in a lot of other tutorials. Tutorials give you the quick solution that might not be the best when you use it every day. This might help some others and the experts might give me some better ideas.
Tip 1: Use the Go Package Manager for Revision Locking
To download the packages your project uses the common advice is to use
go get. This will scan your source files and download any imports you use. Unfortunately, it pulls the HEAD from the repo.
When you're coding for production servers, this creates problems when you want to always use a specific branch or tag of a package. One reason to avoid HEAD is you may want to ensure that the only changes to your service are the ones you make, so when a problem appears you don't realize that one of your servers is running a slightly different library than the others.
The solution I use for this is the Go Package Manager (gpm).
Go Package Manager
gpm is not like NPM, or pip, or many other package managers that pull from a centralized package manager site. Insted gpm is a simple bash script to allow you to specify specific library versions (commits, tags) you want to use and it just pulls from github.com or whichever server you've specified. You can read more here. It allows you to specify the projects you want to use and their specific tag or commit. As an example, here is part of a
Tip 2: Use direnv for per project GOPATHs
If you're using the Go Package Manager, you may want to set your GOPATH variable for each project. Many people use a single GOPATH for multiple projects, so this may not be needed for your setup.
The GPM developer wrote a tool called GVP (Go Versioning Packager) to assist with this. It's simply a bash script that sets your GOPATH. You
cd to your project, then run
gvp, and your
GOPATH is set. I find it easier to use direnv which will automatically do this for me whenever I
cd into the directory.
.envrc file is
export GOPATH="$GVP_DIR:$PWD:`echo $PWD | sed 's/src.*//'`"
GOPATH is set to the current directory and any parent
src directory. So when I run
GOPATH is set to
This allows for the following (simplified) directory structure.
Now in both my
server.go files I can share
Tip 3: Use the Atom editor with the go-plus plugin
All the value of most editors is in in it's plugins and for Atom you'll want to install go-plus. It provides syntax high-lighting and will autoformat your code on save, so it looks standardized. go-plus will also lint your code so it checks for lot's of bugs you might have. You can also get plugins for code completion.
There are lots of other editor options, with many providing at least syntax high-lighting. There are also some sliglty more featureful options, such as theZeus IDE but it is Windows only. The additional capabilities it adds over Atom are code following (go to declaration) and some debugging support via integration with GDB.
Tip 4: Use the latest Go
Chances are if you're on Linux, your package manager installed an older version of Go. You should use the latest version for performance, security, and compatibility reasons. Go 1.4 was released on Dec 10, 2014.
Download and extract the latest version from https://golang.org/dl/
Ensure you have the latest:
$ go version
go version go1.4 linux/amd64
Tip 5: Debug with gdb
I love print statements as much as anyone for debugging, but sometimes you need a debugger. In Go, that means using gdb. One of the main reasons to switch to Go 1.4 is the improved debugging experience.
Even in Go 1.3, I'd get issues with gdb not knowing the names of variables and other issues that made gdb not very useful for Go debugging. With Go 1.4, it's been working much better.
To debug, you'll want to build binaries (do not use
go run server.go and attach to it). You'll build and run as follows:
go build -gcflags "-N -l" server.go
gdb --args ./server --port=8000
That will disable optimizations for the build and then run your code with whatever arguments you might normally use.
When using the GDB debugger for your Go code, you should see be able to set a breakpoint such as on
main function), see your source code, and print the values of your variables. If you can't, something is broken.