Go is a statically-typed compiled language inspired by C in design, but aims to provide memory safety, ease of usage, and the high performance of close-to-metal languages like C++ and Rust, which Go is often compared to. The main overarching difference is that Go makes language design decisions that favour ease of usage over speed.
Notably, Go is credited for improving the developer experience in writing concurrent code with concurrency constructs built into the language. It’s also credited with very fast compilation/build times, which is one reason why Go is prevalent in DevOps.
Go is general-purpose, but it’s typically used for building:
- Backend servers in combination with a framework like Gin.
- Complex scripts and CLIs. For one-off scripts, Python is quicker to write, but for long-lived scripts used frequently, Go might be better.
- Data-intensive algorithms.
I learned Go mainly from the official ‘A Tour of Go’ tutorial and official docs.
All Go programs consist of packages, which consist of source files defining a bunch of functions, variables, etc. Program execution starts in the
Outside of the standard library, there is a rich Go packages ecosystem searchable at pkg.go.dev. This is an awesome community list of packages.
Import statements like
import fmt creates a binding
fmt that lets you access the package’s functions.
- If you do
import math/rand, it uses the last name in the path to create the binding, creating the
randbinding in this case.
- It’s preferred to group import statements into parentheses:
1 2 3 4
import ( "fmt" "math" )
A binding is exported if it starts with a capital letter, otherwise, it remains only accessible within its package. It’s that simple.
Variables are declared with
var and can be done at the package-level or function-level.
- Types always come after the variable/parameter name, like TypeScript. Why? In short, with C-style type declaration, complex types quickly become unreadable, eg.
int (*foo)(int (*)(int, int), int). By specifying the type after the symbol name, you have significantly more readable complex types:
foo func(func(int, int) int, int) int( official blog).
- Uninitialised variables will take on a default value defined by the language standard:
0for numeric types,
const which prevents them from being reassignable after being declared.
# Type System
Go is statically-typed, so the type of every symbol should be known at compile-time.
# Primitive Types
Go’s primitive types include:
int (and all its variants like
complex128 for complex numbers.
Functions declarations look like this in Go.
# Multiple Return Values
Unlike most languages, you can return multiple values without needing to wrap it in a data structure.
# Basic Constructs
All looping is done with
for. You never use parentheses.
Go has regular
else like most languages, but you never use parentheses.
Go has a switch-case construct like most languages, but it’s unnecessary to
break after each case to prevent ‘running through’ each case.