I am definitely not fully proficient at Go yet, but I’m getting there. This post will be about my experiences of Golang and what important things I have learnt so far.
Why Go?
I wanted to find a modern language that was up-and-coming, that also wasn’t too far from what I already know. The 3 that jumped at me after a quick google search were Golang, Swift and F#.
After comparing them, I quickly eliminated swift as it was aimed at Linux and Mac when I use a Windows PC for my development. Although I like Linux, I wasn’t really willing to Lock myself to that OS for development. So really it was between F# and Golang. F# is the most similar to C#, but uses a completely different programming paradigm called Functional Programming. Where as Golang uses Object-Orientated Programming like C#, but has a much stronger emphasis on Concurrency and Clean code. Also the ability to compile Go code to any OS architecture was a big positive to me, as I never need to worry about my applications not running on some peoples machines.
I think this paragraph from the Golang’s docs page sums it up the best.
Go is expressive, concise, clean, and efficient. Its concurrency mechanisms make it easy to write programs that get the most out of multicore and networked machines, while its novel type system enables flexible and modular program construction. Go compiles quickly to machine code yet has the convenience of garbage collection and the power of run-time reflection. It’s a fast, statically typed, compiled language that feels like a dynamically typed, interpreted language.
Getting started with Go
Setting Up Go
One of the most difficult things I found when starting to use go, was setting it up on a computer. Don’t worry if you haven’t tried to install Golang, I will explain in detail my findings and their importance.
The Installer
This really only applies to Windows as I believe its the only OS that has an official installer. Its a fairly simple task, you go to the Go downloads page and download the installer. The installer will download the files you need into the directory specified (C:\Go by default) and set up a number of environment variables that Go needs to function.
The Environment Variables
This is the part that confused me the most as the descriptions given on go’s documentation just confused me at first. Most of them are quite simple so I will get them out the way now.
You can see your Go related Environment variables using go env
.
GOARCH
- This specifies the architecture of your OS. You should never need to change this.GOCACHE
- This is the directory go uses to cache things whilst building projects. You might need to change this if for some reason go didn’t have the correct permissions or something.GOOS
- This specifies the OS that you have. You should never have to change thisGOROOT
- This is the directory to the files downloaded by the installer. You might change this depending If you want to paint go to a different version of the source files.GOEXE
- Specifies what kind of executable file should be created. You should never need to change this.GOPROXY
- Allows you to set a proxy to go through. I have never needed to do this, but I imagine this would be very useful if you were on a business network.
Now onto the more confusing ones:
GOPATH
- This is the path to one or multiple workspaces. Depending on how many workspaces you have, you may need to update this frequently. Basically, when go is asked to build a project it checks to see what packages the project needs. Once it has a list of packages, it looks firstly in the$GOROOT/src
directory and then looks through the$GOPATH/src
directory.GOBIN
- So this setting only applies to the use ofgo install
. If you were to set this toC:\application_bin
, and then rungo install http://github.com/Chris-Greaves/boxup/boxup
, it would createC:\application_bin\boxup.exe
binary file. If this is empty, it will install to$GOPATH/bin
Creating A Workspace
This was something I didn’t get right for a long time, despite the documentation being quite good. There is a specific folder structure you should follow when working with go.
It must look like this:
$GOPATH
├─bin
├─pkg
└─src
Each folder has a specific reason:
bin
- This is where all the compiled executables should go.pkg
- This is where any dependent packages are kept.src
- This is where all the source code goes.
So if you were to create an application called “TestApp” and build it, your structure would look something like this:
$GOPATH
├─bin
│ └─TestApp.exe
├─pkg
└─src
└─TestApp
└─main.go
In the next example I want to go into how to work with multiple packages. By this I mean referencing a different set of .go
files, within your application. Keeping with the TestApp example for above, What if the main.go
file looked like this:
package main
import (
"EasyAPI"
)
func main() {
EasyAPI.CallEndpoint("Version")
}
The file relies on a package called “EasyAPI”, but how does that look in our file structure? Well, remember that go build
will always look at $GOPATH/src
for code. This means our “EasyAPI” package needs to be under $GOPATH/src/EasyAPI
for it to be found and TestApp to compile. Given this, the structure would need to look something like this:
$GOPATH
├─bin
│ └─TestApp.exe
├─pkg
└─src
├─TestApp
│ └─main.go
└─EasyAPI
└─main.go
Its worth noting you can have multiple GOPATHs, meaning you will need the same file structure for each path in GOPATH. So when it comes to running go build
it will look in each path in $GOPATH for src/<package name>
, meaning you could have something like this:
$GOPATH = folder1;folder2/workspaceA;folder2/workspaceB
folder1
├─bin
├─pkg
└─src
└─TestApp
└─main.go
folder2
├─workspaceA
│ ├─bin
│ ├─pkg
│ └─src
└─workspaceB
├─bin
├─pkg
└─src
└─EasyAPI
└─main.go
Lastly I want to talk to you about working with projects hosted on github or something along those lines. If you plan to host your code on a git repo site like Github or Bitbucket, there are a number of things you should take into consideration.
Go has a number of commands that can directly pull code down from repositories.
The most important one is go get
, which will clone the git repository and add it to your $GOPATH (first by default). This is useful when using external libraries, as you can run the command go get github.com/user/repo
to pull down that library and automatically add it to your $GOPATH.
Doing this will create the following folder structure:
$GOPATH
├─bin
│ └─repo.exe
├─pkg
└─src
└─github.com
└─user
└─repo
└─main.go
Note how it creates a folder for all the parts of the URL. If you want your project to be compatible with this feature, you will need to structure your files the same. If your repo is at “github.com/Chris-Greaves/TestApp” then your file structure will need to be:
$GOPATH
├─bin
│ └─repo.exe
├─pkg
└─src
└─github.com
└─Chris-Greaves
└─TestApp
└─main.go
If your application contains multiple packages, you will need to ensure that all references to it contain the Github information as well. For example, if you have a package called “extra” under the TestApp repo you would need import "github.com/Chris-Greaves/TestApp/extra"
and a folder structure like this:
$GOPATH
├─bin
│ └─repo.exe
├─pkg
└─src
└─github.com
└─Chris-Greaves
└─TestApp
├─extra
│ └─extra.go
└─main.go
This works the same of external packages such as “golang.org/x/image/”. If you have import "golang.org/x/image"
when you perform a go get github.com/Chris-Greaves/TestApp
, it will download both the TestApp repo as well as the image repo.
An example of this is my BoxUp repository.
You are now setup, and ready to start developing!
IDEs
Unlike C#, Golang doesn’t come with a recommended IDE. Instead most people use text editors with plugins. I for one use Visual Studio Code, with the Go Extension developed by Microsoft themselves.
Visual Studio Code provides me with everything I needed to get started. It will offer to download useful tools to help you start coding. These tools are such things as Auto Completion and Lint-on-save, but most importantly it will download the delve debugger.
However, if you want an IDE that is fully designed around Golang, then look no further then GoLand. GoLand is a commercial IDE by JetBrains, and comes fully featured with debugger, coding assistance, and much more. But given the annual price tag that comes with it, I haven’t picked it up.
Conclusion
Overall, I am thoroughly impressed with this language and the support around it. Its fast, not that hard to set up when you know what you’re doing, and widely supported by both the community as well as large organisations. I can’t wait to start on my next Go project!