I have heard of Go, but what is it really?
Go (sometimes referred to as “golang”) is a programming language developed by Google. If that did not get your attention, maybe the co-author will: Ken Thompson. He implemented both Unix and the B programming language, which was a direct predecessor of C. Go is a compiled language using a garbage collector. The compiler and other Go tools are all free and open source. Its compiler is self-hosting, meaning the compiler and the tools themselves are written in Go. Go is supposed to be simple, lightweight and clean. It only has 25 keywords!
Ok, but why should I consider trying Go?
For me, it was the cross-platform development. Go can be built for multiple architectures, multiple operating systems in a single line. For example, a developer on a Linux machine can easily build a Windows or macOS executable without any hassle – “GOOS=windows GOARCH=amd64 go build”. The GOARCH variable only needs to be present if we’re building for a different architecture than the machine we’re developing on, for example ARM.
When building an executable, you will notice that it is bigger than usual executables. That’s because the file is compiled as a monolithic executable. This means that the file will contain every single dependency it needs. Essentially, this means that it won’t need any so/dll/dylib files. It creates a dependency-free executable, no need to install anything or have more than one file to copy and run!
The language has a great multi-threading concept called “goroutines”. A goroutine is a function call preceded by the “go” keyword. It spawns a lightweight thread in which that function is executed at almost zero cost.
Another great feature is formatting. Many languages lack a proper formatting tool and in many cases they ignore the code style altogether. Go is slightly different. The style is uniform across all applications, so every source file is formatted the same. Several ways to format the code may also report compile-time errors, which may seem like a downside at first, but it forces you to write readable code.
When you install Go, the tooling comes with a compiler, code formatter, package manager, and a testing framework. This basically means that the majority of tasks are as simple as running “go build” for building a project, “go get” to download dependencies and “go test” to run tests.
OK, I’m sold. How do I start?
Pick your favourite editor or IDE; it probably already has a plugin for Go. If you can’t decide, I would suggest either GoLand (by JetBrains), Visual Studio Code (with Go plugin) or, if you’re feeling hardcore, vim with vim-go plugin. Installers for Go are available at https://golang.org/dl/. If you’re using Linux, the package is probably in your repositories, so you can just use your package manager to install it (sudo apt install go, yum install go, pacman -S go, …). The example “Hello world” follows:
Let’s save that as “main.go”. To run it we can use the terminal command “go run” (which basically compiles and runs the code in the current directory – neat, right?). If we wanted to build an executable we could run “go build” instead. I believe the code here should be pretty self-explanatory: we declare that our file belongs to package main (which is the default Go package), import the “fmt” package, which contains functions for formatting strings and basic I/O. The “fmt.Println()” call basically means “call Println from package fmt”.
How about something more complex?
Let’s create a simple HTTP server. It may sound like a lot of work, but Go has an extensive standard library which contains most things you’d need a third party library for in other languages. Here’s the code that runs an HTTP server, listening on port 8080, returning the “Hello world” message:
Impressive, isn’t it? Naturally, there’s a way to route to multiple endpoints and filter the calls based on the request method, but that’s a topic for another time.
How about OOP?
OOP in Go is slightly different to what you might be used to, in fact it’s probably mostly similar to C (not C++!). Anyone with experience in C development will notice that OOP works mostly in the same way, but with several improvements. Let’s take a look:
The code here defines a structure User, with a public field “Name” and a private field age. “But how can you tell?” you may ask. Simple: all names in lowercase are package-private and the uppercase names are public. We’ve also declared two functions. Notice the thing on the left of the function name? It’s called a receiver. It can be either a pointer or a regular variable. The pointer is used when you want the function to mutate the object or if you want to avoid copying the object. Notice that both the pointer and regular references access the function and variables without ever using the arrow (“->”) operator, like in C. You’ve also probably noticed the “`json:”first_name”`”. These are called tags. They are accessible at runtime using reflection, should you need them. In our case, they can be used to serialize the User object to JSON using the standard library, with the names specified in the tags. Similarly, we can also use tags to associate fields with column names in a database for ORMs, xml serialization, and many more.
How about performance?
Since Go is a compiled language it is a lot faster than the scripting languages like Node.js, Python, etc. In fact, Go is very close to C/C++ when it comes to performance (even though it offers access to runtime reflection and a garbage collector). For example, here are some sample benchmarks for Go: Go vs C, Go vs C++, Go vs Node.js.
That’s all for now, I hope you might consider using Go in one of your future projects.