I love the Go programming language, or as some refer to it, Golang. It’s simple and it’s great.

I write this on a tangent. Didn’t expect Golang to be so good.

I first picked up go around January 2016, it had a relative small but enthusiastic community here in Israel.

I didn’t think much of it at the time, I was honing my programming skills and Golang was just a tool I’ve used to accomplish a task.

Even one year ago, using go was brilliant. The process was straightforward once I’ve got the general hang of the language.

I wrote a crucial piece of code for Visualead, the company I work for, and it didn’t let us down, still running in production a year later with zero maintenance since then.

Recently I found myself again using Golang again, and I felt compelled to write about the reasons I fell in love with Golang.

The GOPATH environment

This is one of the first things you’ll have to handle once you begin writing in Go.

Setup your GOPATH directory anywhere on your computer, complete with bin, src, and pkg directories and you are ready to begin writing.

// How the directory structure looks like:

go

- bin

- pkg

- src

Under my home directory I create a new directory for every programming language I write in. My user home directory is filled with folders like these:

chef

cpp

elixir

elm

go

javascript

meteor

ocaml

php

python

scala

None of these languages enforce this structure besides Go. Go forces you to define a root directory for all of your Golang goodies, and it does it for a good reasons which are coming right up.

The Golang Application

Want to create a new Golang applications? Simple.

Go to your $GOPATH/src directory, create a new folder, create a new file.go , call the package main , add a func main() {} function and that’s it. all of the Go goodies are available to you since that moment forward.

More on Go goodies coming up! but first a few words about the Golang modules.

The Golang Modules

My favorite programming paradigm done right. I see the module system as a sort of alternative to the Object Oriented classes system.

Golang calls it’s modules packages. So from now on everytime we say a module we mean a package and vise-versa.

Module == Package == Module

In Golang every directory you create becomes a package. A package can become an application if it’s name is main .This is helps with a natural separation of code into manageable logical chunks.

You always want your business logic to be created from reusable components, or packages in case of Golang.

In my current app I have to manipulate some lines in some files, and upload them to AWS S3 once i’m done.

My app structure looks like this:

src

- my_app

- - main.go

- - main_test.go

- - uploader

- - - uploader.go

- - - uploader_test.go

- - replace_file_lines

- - - replace.go

- - - replace_test.go

- - - strings_util.go

- - - strings_util_test.go

The _test.go files are of course the way to do unit test files for Golang, which has a testing framework built in it’s core.

Also to those who are coming from an object oriented language, it helps to think that every directory here is a complete static class, and every function or variable inside the .go files becomes it either a property or method.

Here’s a possible example of how replace.go can look like:

If a directory shares more than one .go file, all the methods and variables are shared between the entire package, even the private ones. It helps for separating a package into even smaller chunks and avoiding large single files.

Without going into Object Oriented vs Functional/Procedural, it’s just important to know that the Go creators decided to not include classic classes it the language. Instead opted to use structs/interfaces, and packages of course.

The Golang gofmt

Golang has a convention of how everything is supposed to look, the exact spacing which is needed in each case and each line.

This allows developers to focus on writing code instead waging wars about curly braces locations.

The old {} vs {

} war:

Or perhaps I am only happy because my side won in Go?

Read more about it here: https://golang.org/cmd/gofmt/

The Golang Import

imports are always relative to GOPATH/src . Always. I cannot overstate how much this decisions saves me in frustration.

Warning: the next line is confusing by intention.

When working with other languages you either can use relative/absolute imports, or somehow set a weird import that will allow you to import a file from whoknowswhere location ( I am looking at you Python ).

Go solves it in a unique way. All imports, no matter in which file, will always be relative to GOPATH/src

So in case of my_app, it’s main imports will look like this:

my_app is under src, so we need to mention it first, then we import the packages that exist under my_app , like uploader and replace_file_lines . Notice we are not importing single files, but instead whole packages. Works like a charm and causes ZERO confusion.

Furthermore, Golang won’t compile unless you actually use the packages you import, this tiny feature helps you to know that every import is actually used.

Expecting your programmers to write a clean code without unused imports? why won’t you let your local Gopher take care of that?

The Golang Get System

The import sections leads us to the next great feature of Golang, the go get feature. While others are impressed with JavaScripts NPM package manager, Go just uses any git repository as it’s package manager.

How does it work?

I’ve wrote before that I needed to upload to S3 right? well then that means I need to AWS SDK to accomplish that.

To make this work, I just open my terminal and write:

go get github.com/aws/aws-sdk-go

What’s going on here? Nothing special, Golang just downloads the repo from https://github.com/aws/aws-sdk-go into your GOPATH/src directory.

Then all you have to do to use the aws-sdk is just import it:

Remember that all imports are relative to the GOPATH/src ? From that you can understand that the s3 package for example resides now under GOPATH/src/github.com/aws/aws-sdk-go/services/s3 .

Simple. Elegant. Another star for the Gopher.

The Golang Build and Package Systems

We’ve been focusing so far on GOPATH/src but there are still other directories we need to address, GOPATH/pkg and GOPATH/bin .

Golang is a compiled language, it means that the code has to be compiled in order to run. Golang is compiled fast. How does it work?

Everytime your compile your code to run it, Golang creates a .a file in the same path as your package, only under the GOPATH/pkg directory. It means that if you compiled the aws-sdk for example. It’ll be compiled once, and shared between all of your other code.

Of course this is not the only reason Golang compiles fast, but it’s just an intro that helps you to understand the role of GOPATH/pkg

Now, what about GOPATH/bin ? When you run the go install command, go creates a binary file, and places it under GOPATH/bin , the file gets the name of your main package’s directory my-app in our case.

Why is it so great? Well you can add GOPATH/bin into your global PATH variable, and all binaries your build are available in your command line, without you doing any extra work! ( Isn’t it great :D ? )

The Golang Cross Platform Builds

Deploying to other distributions instead of the one you are writing your code on? Well don’t worry, you don’t need to have a windows machine to build your code for windows. Golang got you covered.

Just run:

GOOS=windows GOARCH=amd64 go install

And our code will output a binary ready to deploy on a windows machine. The .exe file will appear at GOPATH/bin/windows_amd64/my_app.exe . Like a walk in the park.

The Golang Language

Golang is aimed to be a simple language.

I love the following post asking why Go wasn’t designed to be a functional language: https://www.quora.com/Why-wasnt-Go-written-as-a-functional-language

“Programmers working at Google are early in their careers and are most familiar with procedural languages, particularly from the C family. The need to get programmers productive quickly in a new language means that the language cannot be too radical”

And simple it is.

Here’s a list of some features Golang doesn’t support:

Classes Operators overloading Function overloading Optional Parameters exceptions

While sometimes I find myself missing language features when writing in Go, I can always do everything that I want. Just sometimes it requires more writing and sometimes thinking. The bottom line is, it leads to code which is easier to reason with because it’s less abstract.

It sometimes amazes me how fast I can achieve a goal when writing in Go, without having years of experience, just because the language is so accommodating and clear.

The Golang Concurrency

I have left the concurrency talk by intention to be last. Why? because I don’t think it’s so important.

It’s an amazing feature of the language. But sometimes it’s presented as the essence of Go, which I believe it is not.

Therefore let me try to sum it up in one paragraph.

Yeah, Golang has great concurrency. You don’t deal with threads but rather create cheap goroutines which are simple to make and manage. Goroutines allow you to distribute the load across all of your CPUs without worrying on how to manage it all.

Still interested in understanding goroutines? Read about them here: https://tour.golang.org/concurrency/1

Update 2017–06–13:

Check Inanc Gumus’ response to read an interesting take about Golang’s Concurrency

The Golang Gopher

Come on, he’s just so CUTE!