The lazy intro to Go

Nick Kobishev
Similarweb Engineering
6 min readFeb 20, 2022
Lazy hippo laying on the ground
Photo by Tim De Pauw on Unsplash

This post is a distillation of an “intro course” I conducted at Similarweb almost exactly 1 year ago. With one session a week for a month, I led a dozen engineers coming from different backgrounds and teams in the company through important topics with examples and resources that should lay the foundation for working with Go in their day to day.

The “lazy” part in the title is mostly about me deferring to external sources. I’ll use sources I value and refer to whenever I need a refresher instead of writing a lengthy post rehashing the original authors.

What is this going to be about and who might benefit from reading this?

In this post:
I will not attempt to comprehensively cover everything there is to cover when starting with Go. Meaning this might not be the best guide for newcomers to the software development world.
What I will be doing is going through some foundational steps in starting with a new language, discussing language features and gotchas, linking to useful resources, asking and answering questions that were asked during the initial run of this course.

This post is mostly targeted towards people with some previous software engineering experience. As I said, this is not a comprehensive intro to the Go language.

*If you’re an experienced Go developer, you might still find some new information in this post, maybe a gotcha or two you weren’t familiar with. Although my previous post might be a better fit for you:
Moving From NodeJs To Go — Doing More, Faster For Less

Prepare you favourite IDE / text editor

The 2 most common IDEs in our company are VS Code with this extension or the right IDE for the job from JetBrains. In this case it’s Goland.

Unfortunately there is no community version for this Goland. You can still try it for 30 days, use pre-release versions or this official plugin if you happen to have an IntelliJ IDEA Ultimate license.

Getting started

The two most important links I can give to start your Go journey are the Tutorial, which will help you set up the basic requirements to working with Go, and the Tour of Go which is intended to make you familiar with the language and its features.

meme of a hand holding a hamster with text saying “it’s dangerous to go alone, take this”

Straight to work

Gophercises are a free course that will get you building actual working code in no time!
After signing up we can start with Exercise #1: Quiz Game.

After watching Overview and Solution- Part 1 and following along I got these 2 questions from the participants.

Q&A #1
Q: I’m a little confused on how to work with slices of slices. When passing a slice to a function it is passed by reference, not unlike pointers. When should I use pointers to slices if ever?
A: A short explanation can be found here. Additionally I highly recommend you copy the code to your favourite editor to get code highlights and make it more readable. Another short and good read is this post.

Q: When should I use a pointer receiver vs value receiver struct methods?
A: This answers the question thoroughly:
Value receiver vs. pointer receiver — Stack Overflow

Now we can get to Solution — Part 2 here and finally get to some concurrency!

Same deal here, watch and follow along. Try to write some code without peeking, practice makes perfect!

a gif of a person lifting bottles as if they are working on their biceps

While you’re at it try to keep these questions in mind:

  • Do I understand why reading from a channel blocks code execution?
  • Am I comfortable with Timers and Channels?
  • Do I understand how anonymous functions and closures work?
    If you think you do, you should try and guess what will happen here.

If you answered “no” to any of these questions I strongly suggest you go over the concurrency part of the Go Tour again.

Q&A #2

Q: How does select work and what’s the order of the case evaluation?
A: This stack overflow answer has a rather good explanation.

Q: How do channels work internally?
This is optional knowledge, so feel free to skip this
A: Go is a “lower level” language so expect some C-like code if you follow this link.

Q: Any idea why standard library slices and maps have different ways to access values and iterate through? This causes confusion and it’s not easy to remember.
A: I was unable to find any concrete explanation as to why it works like it does, but it seems to make sense, in my opinion.
Anyways, maybe this playground should clear this up.

You can also read a more detailed explanation here:
https://blog.golang.org/maps
https://blog.golang.org/slices-intro
If it’s still unclear, please comment and I’ll do my best to clear this up.

Structs and Interfaces

Let’s start with a reading list, the following posts are a great resource when it comes to in depth information about structs and interfaces:

Things to note about struct types:

  • Field names may be specified either implicitly with a variable or as embedded types without field names. In this case, the field must be specified as a type name T or as a pointer to a non-interface type name *T
  • Field names must be unique inside a struct type
  • A field or a method of an embedded type can be promoted
  • Promoted fields cannot be used as field names in the struct
  • A field declaration may be followed by an optional string literal tag
  • An exported struct field must begin with a capital letter
  • Apart from basic types, we can also have function types and interface types as struct fields

More details about the struct type can be found here in the language specification.

Things to note about interface types:

  • The zero value of an interface is nil
  • An empty interface contains zero methods. Note that all types implement the empty interface. This means that if you write a function that takes an empty interface{} value as a parameter, you can supply that function with any value
  • Interfaces generally belong in the package that uses values of the interface type and not the package that implements those values

More details about the interface type can be found here in the language specification.

Error handling

A blog post from the official Go blog, I know it’s from 2011 but it’s still basically the way to go, with a few improvements that were added in later versions:
Error handling and Go — The Go Programming Language

Another more recent blog post is this one:
Working with Errors in Go 1.13 — The Go Programming Language

Panic

at the disco

Another oldie, but it is a goodie!
Defer, Panic, and Recover — The Go Programming Language

Honestly I don’t have much to say about panics just because it’s rarely a case where you’ll use a panic and not just return an error.
This pretty much covers it.

Best practices

A few simple ideas to always keep in mind are the Go Proverbs!
If you consider them when working on your next project, you’ll be sure to improve your code quality tenfold.

I would love to hear from you in the comments if you find anything unclear/incorrect!

--

--

Nick Kobishev
Similarweb Engineering

Principal Engineer@Similarweb, tech blogger, and public speaker. Fan of Big Data and big doggos.