Start on your first Golang project

A couple of months ago I started to do some coding in Go a.k.a Golang. Not only because they have an awesome logo ;-). My main reason was because I wanted to have something running as bare metal as possible on my Raspberry Pi and I wanted to have it available for different platforms to be easy to install. Some other reasons are the ease of creating async code by using Go in front of your methods and the unique approach of channels to sync between go routines (threads). I have been reading a lot about Go since it was released in 2012, now it was time to really get my hands dirty and try it for myself.

Curious, continue reading…

What is Go

Go is an open source programming language that makes it easy to build simple, reliable, and efficient software. It originates from Google and has been one of the fastest growing and adopted programming languages of 2018. Go was first released in March 2012. Recently since Go 1.11 release it also has support for modules, meaning it came a bit more convenient to manage your dependencies.

Setup environment

To start you first need a good setup for our development setup. As you might already have noticed in my last article bonus section I have an easy way to get my tooling installed using Chocolatey.

On Windows we use Chocolatey in Powershell to install Go and vscode.

Windows Powershell as administrator
1
cinst -y go vscode

With Go and vscode installed we have all we need to start.

As I prefer Git bash for all my remainder scripting I run the following Visual Studio Code command from Git Bash to install the go extension. You can also just install the extension from vscode itself if you want.

Windows Git bash
1
code --install-extension ms-vscode.go

With the Go extension installed in visualstudio we now have everything in place for a nice coding experience.

Where to find great go resourses

Go’s documentation can be found here. All packages available for you to use in your own go programs can be cound here. Furthermore there is an online playground where you can try out things or use it to help out a fellow programmer with examples.

Create your first project

To start with a new go project we first create an empty folder. Then we type go modules init in this folder to initialize the go modules. Go modules are used for our dependencies.

1
2
3
mkdir hello-world
cd hello-world
go mod init github.com/marcofranssen/hello-world

Syntax

In Go we define a function using the func keyword.

1
2
3
func main() {
// our code
}

Something which comes closest to what we know from other languages as a class is a struct. You can define a struct as following.

1
2
3
type Envelope struct {
Message string
}

In go all variables, functions, structs which start with an upper case are public. All variables, function, structs which start with lowercase are package private. Furthermore type definitions come behind the variable name, which you might already have noticed int he struct example above. To import other packages you simply put an import statement on top of the file. Last but not least every go program must have at least one main package.

1
2
3
4
5
6
7
8
9
10
11
package main

import "fmt"

func SayHi(person string) string { //public function
return fmt.Sprintf("Hi %s", person)
}

func sayHi(person string) string { //private function
return fmt.Sprintf("Hi %s", person)
}

The fmt package brings us some nice features like template strings which you can use to build a string using some variables. Furthermore we can see the return type for a function is mentioned at the end of the function definition. For further details on the fmt package see the documentation.

Ready to rumble

Now we have an empty project in place and we know a bit about the syntax we can start by opening this folder in vscode.

1
code .

We first add a new file to our folder which we call main.go. Then lets add some code we discussed above.

main.goplayground
1
2
3
4
5
6
7
8
9
10
11
package main

import "fmt"

func main() {
fmt.Println(sayHi("Marco"))
}

func sayHi(person string) string {
return fmt.Sprintf("Hi %s", person)
}

With above code we can now run our application by using the following command on our commandline.

1
go run main.go

You can also test it out in the Go playground.

Test

To add tests in go we simply add the following file. main_test.go. In here we can add a function to test our sayHi method. The signature for test methods MUST always be TestXxx(t *testing.T). The First X must always be uppercase.

main_test.go
1
2
3
4
5
6
7
8
9
10
11
package main

import "testing"

func TestSayHi(t *testing.T) {
expected := "Hi Marco"
greeting := sayHi("Marco")
if greeting != expected {
t.Errorf("Greeting was incorrect, got: '%s', want: '%s'", greeting, expected)
}
}

Above we covered some new things. We use the shorthand to assign values to a variable :=. When the sayHi function doesn’t return the value we expect we will error with a nice understanable message.

Now to run our test we can simply do the following from out commandline. Note the ./... is my approach to run all tests from all files and subfolders in my project.

1
go test ./...

Please also go ahead by changing the implementation and run the test again to see how the tests will fail. To run with code coverage you can run the tests like this.

1
2
go test -coverage -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html

For further reference please check the docs of the testing package.

Compile and Run

The easiest way to build an executable for our software is by doing the following.

1
2
go build .
./hello-world.exe

This will create us a Windows executable as we are on Windows. You can simply invoke the executable and see the same result as we had with go run main.go. To get some more verbose output and see what is happening behind the scenes you can use the -x option on go build. So how do we compile the same code for Linux or our Raspberry Pi?

Linux amd64 processor architecture binary
1
GOOS=linux GOARCH=amd64 go build .

To run this binary on Linux don’t forget to chmod +x and then simply invoke using ./hello-world.

A Raspberry Pi 3 has an ARM v7 architecture which can be compiled like this. NOTE: we can do all of this from our Windows machine.

Linux arm v7 processor architecture binary
1
GOOD=linux GOARCH=arm GOARM=7 go build .

To run the binary simply do the same as on any other Linux machine. chmod +x and then ./hello-world to run your application.

Wrapup

I know this application is super simple and not very useful, but at least you have your development environment setup now and got some handson experience in writing the first few lines of Go. You also know how to write tests for your code. That should be a good basis for writing some high quality code. The more cool stuff like go routines I would like to save for a new blogpost as we would also have to cover the channels.

Last but not least I would like to point you to my very first application in Go which is an integration with the Nest thermostat which I run on my Raspberry Pi to collect my temperature data and plot it in a nice React web application. Also don’t forget to sign up at the Gophers Slack workspace.

In the comments feel free to ask any questions or give feedback to my blog.

Share