til

Today I Learned: collection of notes, tips and tricks and stuff I learn from day to day working with computers and technology as an open source contributor and product manager

View project on GitHub

Learn Go

This is my initial TIL on learning Go, it provides some basic notes and a lot of links to great Go resources to get your started, so if you are past the “Hello World” introduction, just skip to the end of not please read the through the implementation, where I will cover some basic Go details.

Let’s go

You can try this out at the Go playground or install the Go compiler on your local machine, I assume and prefer the latter.

// helloworld.go
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

We can run our go program:

$ go run helloworld.go
Hello, World!

Or we can build with an explicit build step, providing us with an executable, which can then be run:

$ go build helloworld.go
$ ./helloworld
Hello, World!

A variation of this implementation of hello world, can be found at the official Go website.

I can recommend taking the tour of Go, which gives a brief overview of the Go language and this brief introduction on how to write Go code will really get you going.

Anyway lets break down our example and process for the above example.

Line 1: is a comment, I have just put the suggested file name for later use

Line 2: a Go file should always contain a package

Line 3: Whitespace is insignificant, but improves readability if used widely, this is however not Go specific

Line 4: We import the package fmt, pronounced fumpt

We can import all the packages we need, the recommendation for importing several packages is the following construct:

import (
    "fmt"
    "math"
)

Actually tools like golint will help you out with this automatically, but let us save that for later.

Line 6: This is function declaration

Just like in C, the main function is special it acts as the entry point to our executable.

In general functions can take input (parameters) and return values. main is special and does not take any parameters and does as default not return anything, which makes it really hard to test (do read this post on the topic), that aside, lets have a look at go functions in general.

A function with no parameters and no return values (just like main), would have the following signature:

func f() {...}

A function with a single parameter:

func f(number int) {}

Two parameters and a return value:

fun f(operand1, operand2 int) int {}

Two parameters and a two return values:

fun f(operand1, operand2 int) (int, int) {}

There are more variations to function declarations, do checkout the documentation or a cheatsheet.

Anyway to set us back a bit, some would say that we did this the wrong way around, we should have written tests first.

So lets add some tests, so make sure our “hello world” implementation in Go works as expected.

This requires that we dwelve into Go modules and Go testing and as stated earlier testing main is hard.

So lets structure our code so we can test it more easily.

package main

import (
    "fmt"
)

func main() {
    fmt.Printf("%s", HelloWorld())
}

// HelloWorld returns universal programming language greeting in english
func HelloWorld() string {
    return "Hello, World!"
}

And we implement a test suite in a file: main_test.go

package main

import "testing"

func TestHelloWorld(t *testing.T) {
    expected := "Hello, World!"
    if observed := HelloWorld(); observed != expected {
        t.Fatalf("HelloWorld() = %v, want %v", observed, expected)
    }
}

Now lets go over the test suite in this file.

Line 1: defines the same package as our helloworld.go (above)

Line 3: imports the package testing

Line 5-10: implements a test function, just as the function I described and implemented for the main body of our program.

The function is named TestHelloWord and it takes the following arguments:

  • t. which is a pointer of the type: testing.T

Next line sets up our expected result, the string: Hello, World!.

The following line executes our HelloWorld function and tests if we our return value is not matching our expected result from the previous line.

If it does not match we fail the test using t.Fatalf and output some diagnostics, to help us address potential issues in our implementation.

This is not the case of this vary basic test.

When doing go test we are however met with and error cannot import "main

So we can tell our go toolchain that we are working on a module

go mod init helloworld

This will create a file: go.mod, with the following contents:

module helloworld

go 1.16

And now we can run out test

go test

The go.mod file, is for our Go toolchain.

Line 1: tells us the name of our module

Line 3: specifies the version of our Go use for our module

There are plenty of awesome resources to get you started with Go, I can really recommend the following articles:

I will continue my journey and added more TILs on different aspects of Go programming and learning Go - good luck and have fun…

Resources and References

  1. A tour of Go
  2. How to write Go code
  3. Learn Go with Tests
  4. Go by Example
  5. Effective Go
  6. Go go-to guide
  7. Official Go Website
  8. Idiomatic Go

  9. Go Developer Roadmap 2020
  10. Algorithms with Go
  11. Go Standard Packages

  12. StackOverflow: “Go: Meaning of the ‘fmt’ package acronym”