Introduction
- Go in 100 Seconds • Fireship 📺
- A Tour of Go • Go 📕
- Learn GO Fast: Full Tutorial • Alex Mux 📺
- Learn Go in Y Minutes • Learn X in Y Minutes 📖
- Learn Go with Tests • Chris James 📕
- Go is Surprisingly Easy • Awesome Code 📺
- Should you learn Go in 2023? • Dreams of Code 📺
- Go Tutorial for Beginners • Nana Janashia 📺
- Learning a new language, or how I gained familiarity with Go · Jamie Tanna | Software Engineer
General
- Effective Go • Go 📖
- 100 Go Mistakes and How to Avoid Them • Teiva Harsanyi 📕
- Go by Example • Mark McGranaghan and Eli Bendersky 📕
Packages & Modules
- Every Go program is made up of packages
- Programs start running in function
main
of packagemain
import
- When importing a package, you can refer only to its exported (capitalized) names
Functions
func ExportedFunction() {}
func unexportedFunction() {}
- A function can take zero or more arguments
- A parameter’s type is declared after its name:
x int, y int
- When consecutive parameters share a type, you can omit the type declaration from all but the last one:
x, y int
- A parameter’s type is declared after its name:
- A function can return any number of results
- Return types are declared in
()
:(string, string)
- Values can be return explicitly:
return x, y
- Or implicitly if the returned variables are named in the return type: if
(x, y int)
, thenreturn
will implicitly returnx
andy
- Return types are declared in
Variables
var names types
- The
var
statement declares a list of variable names optionally followed by their types and/or initial values:var c, python, java bool
- A
var
statement can occur at the package or function level - A
var
declaration can optionally include initial values, in which case the explicit types can be omitted since the variables types are inferred from the values on the right hand side:var c, python, java = true, false, "no!"
- Variables declared with no initial value are assigned their “zero value” (
false
for booleans,0
for numbers,""
for strings) - A variable’s type can never change (Go is a “strongly typed” language)
- The
:=
short assignment statement- An alternative to a
var
declaration with an implicit type- e.g.
var i int = 42
can be replaced withi := 42
- e.g.
- Only available inside functions (since every package-level statement must begin with a keyword)
- An alternative to a
const names types
- Constants are declared like variables, with a few exceptions:
- They must be initialized with a value
- Their value can never change
- They can be character, string, boolean, or numeric values
- They cannot be declared using the
:=
syntax.
- Naming:
- PascalCase or camelCase
- A variable is exported if its name begins with a capital letter (e.g.
YouCanImportMe
) - Any “unexported” names are not accessible from outside the package (e.g.
youCannotImportMe
)
Types
- The expression
T(v)
converts the valuev
to the typeT
- e.g.
bool()
- e.g.
- Explicit conversion to a compatible type is required when assigning values of one type to a variable with another, or when operating on values of different types (e.g. with
+
)
Booleans
bool
Numbers
- When you need a non-floating-point number, you should use
int
unless you have a specific reason to use a sized or unsigned integer type int
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,uintptr
float32
,float64
complex64
,complex128
- The
int
,uint
, anduintptr
types are usually 32 bits wide on 32-bit systems and 64 bits wide on 64-bit systems
Strings
string
- Stored as array of bytes, not characters
- Special (non-ASCII) characters (e.g. emoji) may comprise multiple bytes
- UTF-8
byte
= alias foruint8
rune
= alias forint32
that can represents a Unicode code point- Implications for index lookups
Pointers
- A pointer holds the memory address of a value
- The type
*T
is a pointer to aT
value; its zero value isnil
- The
&
operator generates a pointer to its operand - The
*
operator denotes the pointer’s underlying value; this is known as “dereferencing” or “indirecting” - Golang pointers explained, once and for all • JamieDev 📺
Structs
- A
struct
is a collection of fields - Struct fields are accessed using a dot
- Struct fields can be accessed through a struct pointer
- To access the field
X
of a struct when we have the struct pointerp
we could write(*p).X
. However, that notation is cumbersome, so the language permits us instead to write justp.X
, without the explicit dereference
Arrays & Slices
- The type
[n]T
is an array ofn
values of typeT
- e.g.var a [10]int
- An array’s length is part of its type, so arrays cannot be resized
- A slice, on the other hand, is a dynamically-sized, flexible view into the elements of an array
- In practice, slices are much more common than arrays
- The type
[]T
is a slice with elements of typeT
- A slice is formed by specifying two indices, a low and high bound, separated by a colon:
a[low : high]
- This selects a half-open range which includes the first element, but excludes the last one
- e.g.
a[1:4]
creates a slice which includes elements 1 through 3 ofa
Generics
- Type placeholders that enable functions to apply the same logic to multiple possible input types
Flow Control Statements
- Conditionals
if short statement; condition {} elseif condition {} else condition {}
()
are not needed around conditions, but{}
are required around each block- Any variables declared in the optional short statement can be referenced in the following
if
/else
conditions and blocks
- Loops
- Go has only one looping construct, the
for
loop for init; condition; post {}
()
are not needed, but{}
are required- The init and post statements can be omitted (resulting in what other languages call a
while
loop) - The condition expression can also be omitted, resulting in an infinite loop
- Go has only one looping construct, the
- Switches
- A
switch
statement is a shorter way to write a sequence ofif - else
statements - It runs the first case whose value is equal to the condition expression, then automatically skips the rest
- In effect, the
break
statement that is needed at the end of each case in other languages is provided automatically in Go - A switch without a condition is the same as
switch true
, which can be a clean way to write long if-then-else chains
- A
- Defers
- A defer statement defers the execution of a function until the surrounding function returns
- The deferred call’s arguments are evaluated immediately, but the function call is not executed until the surrounding function returns
- Deferred function calls are pushed onto a stack. When a function returns, its deferred calls are executed in last-in-first-out order
- Defer, Panic, and Recover • The Go Blog 📖
Interfaces & Methods
reader io.Reader
writer io.Writer
Concurrency
- Concurrency vs parallel execution
- Goroutines
- WaitGroup
- Wait
- Mutexes
- Lock/Unlock
- RLock/RUnlock
- Be careful to include as few lines as possible inside the lock to avoid unnecessary blocking time
- Confinement
- Avoiding the bottlenecks caused by locking by instead “confining” the operations that need to be safe to a different subset of the data than is accessed by the other Goroutines
- Improve Go Concurrency Performance With This Pattern • An example of refactoring from locks to each Goroutine operating on a reference to a specific index in the slice all the Goroutines reference • Kantan Coding 📺
- Channels
- Goroutines that pass data around
- They hold data
- They are thread safe (avoiding race conditions when reading/writing data to memory)
- Allow listening for data to be added or removed from a channel and blocking code execution until those events occur
- Buffer channel = channel that can store multiple values
- golang context package explained: the package that changed concurrency forever • Kantan Coding 📺
- Gist of Go: Concurrency • Anton Zhiyanov 📕
Debugging
fmt.Printf("%T %v %q", x, y, z)
%T
= variable’s type%v
= non-string variable’s value%q
= string variable’s value
Building Web Apps
- Let’s Go! • A start-to-finish guide to building web apps with Go • Alex Edwards 📕
- Let’s Go Further! • Advanced patterns for APIs and web applications in Go • Alex Edwards 📕
- The standard library now has all you need for advanced routing in Go. • Dreams of Code 📺
- Go + HTML + TailwindCSS? • Livestream building a Go server + HTML frontend via Templ • Dreams of Code 📺
Comparison to Rust
- Go vs Rust: Which To Learn In 2024? • Kodaps Academy 📺
- Rust vs Go: Which is best? THE Definitive Answer • Michael Mullin 📺
- I want off Mr. Golang’s Wild Ride • Faster than Lime 📖
- Lies we tell ourselves to keep using Golang • Faster than Lime 📖
- Why Go Or Rust On New Projects • Favourable comparison of Go vs Rust for most projects • The Primeagen 📺
- Why I Use Golang In 2024 • The Primeagen 📺
- Rust vs Go in 2024 • John Arundel 📖
Inbox
-
Command-line Interfaces (CLIs) - The Go Programming Language - Go
-
Frequently Asked Questions (FAQ) - The Go Programming Language - Go
-
Early Impressions of Go From a Rust Programmer | by PingCAP | Better Programming - PingCAP
-
Error handling in Go: Best practices - LogRocket Blog - Raphael Ugwu
-
Go is Boring… And That’s Fantastic! - Jonathan Bodner
-
err != nil Is GOOD? (And Why) - The Primeagen
-
Go’ing Insane Part One: Endless Error Handling - Jesse Duffield
-
Using Go instead of bash for scripts - Krzysztof Kowalczyk 📖
-
What made you choose Rust over Go? - The Rust Programming Language Forum - Rust User Forum
-
Learning a new language, or how I gained familiarity with Go • Jamie Tanna 📖
-
Learn Go Programming - For Beginners - Programiz
-
Five of my favorite project ideas to learn Go. • Todo app (CLI + CSV), web API (calculator endpoints), web scraper (dead link finder), URL shortener, Currency converter (TUI) • Dreams of Code 📺
-
Go structs are copied on assignment (and other things about Go I’d missed) • Julia Evans 📖
-
Golang Project: Building a Secure Login Portal • Good demo of quickly building an API with a protected route that supports logging in with a password, session cookie and CSRF cookie • Alex Mux 📺
-
Designing Go Libraries | Abhinav Gupta - Abhinav Gupta