Open to remote roles
Copied ✓
Language Reference Go · Golang Concurrency · Interfaces · Channels Click any operator or button to copy

Go Language
Cheat Sheet

A complete annotated reference for Go — from basic syntax through concurrency primitives, interfaces, embedding, and production snippets. Example code adapted from A Tour of Go. Click any operator or code copy button to copy to clipboard.

18
Sections covered
Go
Statically typed
Goroutines possible
0
Classes (only structs)
Imperative & statically typedCompiled to native code — no JVM, no interpreter overhead.
C-like syntaxFewer parentheses, no semicolons. Structure similar to Oberon-2.
No classesStructs with methods instead. No implementation inheritance — use embedding.
InterfacesImplicitly satisfied. No implements keyword needed.
First-class functionsFunctions are values. Closures are lexically scoped.
Multiple return valuesFunctions can return multiple results — idiomatic error handling.
PointersYes, but no pointer arithmetic. Safe by design.
Built-in concurrencyGoroutines (lightweight threads) and Channels as first-class primitives.

Hello World

File hello.go — run with $ go run hello.go

go · hello.go
package main import "fmt" func main() { fmt.Println("Hello Go") }

Arithmetic

➕ Arithmetic Operators
click operator to copy
OperatorDescription
+Addition
-Subtraction
*Multiplication
/Quotient
%Remainder
&Bitwise AND
|Bitwise OR
^Bitwise XOR
&^Bit clear (AND NOT)
<<Left shift
>>Right shift

Comparison

🔍 Comparison Operators
click operator to copy
OperatorDescription
==Equal
!=Not equal
<Less than
<=Less than or equal
>Greater than
>=Greater than or equal

Logical

🧠 Logical Operators
click operator to copy
OperatorDescription
&&Logical AND
||Logical OR
!Logical NOT

Other

🔧 Other Operators
click operator to copy
OperatorDescription
&Address of / create pointer
*Dereference pointer
<-Send / receive operator (see Channels)

Variable & Constant declarations — type goes after identifier

go · declarations
var foo int // declaration without initialization var foo int = 42 // declaration with initialization var foo, bar int = 42, 1302 // declare and init multiple vars at once var foo = 42 // type omitted, will be inferred foo := 42 // shorthand — only in func bodies, type always implicit const constant = "This is a constant" // iota — incrementing numbers starting from 0 const ( _ = iota // 0 (skipped) a // 1 b // 2 c = 1 << iota // 8 (2^3) d // 16 (2^4) ) fmt.Println(a, b) // 1 2 fmt.Println(c, d) // 8 16

Functions — parameters, multiple returns, closures, variadic

go · function signatures
func functionName() {} // simple function func functionName(param1 string, param2 int) {} // with parameters func functionName(param1, param2 int) {} // multiple params, same type func functionName() int { return 42 } // return type declaration // Multiple return values func returnMulti() (int, string) { return 42, "foobar" } var x, str = returnMulti() // Named return values — return with no arguments func returnMulti2() (n int, s string) { n = 42 s = "foobar" return // n and s are returned implicitly }
go · functions as values & closures
func main() { add := func(a, b int) int { return a + b } // assign function to variable fmt.Println(add(3, 4)) // call by name: 7 } // Closures — lexically scoped; the function captures outer_var func scope() func() int { outer_var := 2 foo := func() int { return outer_var } return foo } // Mutation through closure func outer() (func() int, int) { outer_var := 2 inner := func() int { outer_var += 99 // mutates outer_var from enclosing scope return outer_var } inner() return inner, outer_var // returns func and mutated value (101) }
go · variadic functions
// ... before type name = zero or more of that parameter func adder(args ...int) int { total := 0 for _, v := range args { total += v } return total } func main() { fmt.Println(adder(1, 2, 3)) // 6 fmt.Println(adder(9, 9)) // 18 nums := []int{10, 20, 30} fmt.Println(adder(nums...)) // 60 — spread slice with ... }

Go's predeclared types — all from the builtin package

go · built-in types
bool string int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr byte // alias for uint8 rune // alias for int32 ≈ Unicode code point float32 float64 complex64 complex128
boolstringintint8int16int32int64uintuint8uint16uint32uint64uintptrbyterunefloat32float64complex64complex128

Explicit conversions — Go has no implicit casting

go · type conversions
var i int = 42 var f float64 = float64(i) var u uint = uint(f) // Shorthand (inside functions) i := 42 f := float64(i) u := uint(f)

Package visibility — upper vs lower case

Visibility rules
Upper case identifier = exported (visible from other packages)  ·  Lower case identifier = private (not visible from other packages)
go · packages
package main // declaration at top of every source file // executables are in package main import "math/rand" // import path math/rand → package name: rand // convention: package name == last segment of import path Exported := "visible" // Upper case = exported unexported := "private" // lower case = package-private

If — with optional pre-statement

go · if / else
// Basic if x > 10 { return x } else if x == 10 { return 10 } else { return -x } // Pre-statement before condition (a is scoped to the if block) if a := b + c; a < 42 { return a } else { return a - 42 } // Type assertion inside if var val interface{} = "foo" if str, ok := val.(string); ok { fmt.Println(str) }

Loops — only for, no while

go · for loops
for i := 1; i < 10; i++ {} // classic C-style for for ; i < 10; {} // while-loop equivalent for i < 10 {} // omit semicolons when only condition for {} // infinite loop — while(true) // break/continue with labels on outer loop here: for i := 0; i < 2; i++ { for j := i + 1; j < 3; j++ { if i == 0 { continue here } fmt.Println(j) if j == 2 { break } } }
Key point
Go has only for — no while, no until. The three forms cover all loop patterns. Labels allow break and continue to target an outer loop explicitly.

Switch — cases break automatically, no fallthrough

go · switch
// Basic switch — cases break automatically switch operatingSystem { case "darwin": fmt.Println("Mac OS") // no fallthrough by default case "linux": fmt.Println("Linux") default: fmt.Println("Other") } // Pre-statement (os is scoped to the switch) switch os := runtime.GOOS; os { case "darwin": ... } // Comparisons in cases (no switch value → acts like if-else chain) number := 42 switch { case number < 42: fmt.Println("Smaller") case number == 42: fmt.Println("Equal") case number > 42: fmt.Println("Greater") } // Comma-separated case values var char byte = '?' switch char { case ' ', '?', '&', '=', '#', '+', '%': fmt.Println("Should escape") }

Arrays — fixed length, length is part of the type

go · arrays
var a [10]int // array of 10 ints — length is part of the type a[3] = 42 // set element i := a[3] // read element var a = [2]int{1, 2} // declare and initialize a := [2]int{1, 2} // shorthand a := [...]int{1, 2} // ellipsis → compiler figures out length

Slices — dynamic length, backed by an array

go · slices
var a []int // slice — unspecified length var a = []int{1, 2, 3, 4} // declare and initialize a := []int{1, 2, 3, 4} // shorthand chars := []string{0:"a", 2:"c", 1:"b"} // ["a", "b", "c"] var b = a[lo:hi] // slice from index lo to hi-1 var b = a[1:4] // indices 1, 2, 3 var b = a[:3] // missing low → 0 var b = a[3:] // missing high → len(a) a = append(a, 17, 3) // append items c := append(a, b...) // concatenate slices a = make([]byte, 5, 5) // make(type, length, capacity) a = make([]byte, 5) // capacity is optional // Slice from array x := [3]string{"Лайка", "Белка", "Стрелка"} s := x[:] // slice referencing x's storage

Operations on Arrays and Slices

go · range iteration
len(a) // built-in function — not a method/attribute // iterate with index and element for i, e := range a { } // only the element for _, e := range a { } // only the index for i := range a { } // variable-free (Go 1.4+) for range time.Tick(time.Second) { // execute once per second }

Maps — key/value store, reference type

go · maps
m := make(map[string]int) m["key"] = 42 fmt.Println(m["key"]) delete(m, "key") elem, ok := m["key"] // ok is false if key not present // Map literal var m = map[string]Vertex{ "Bell Labs": {40.68433, -74.39967}, "Google": {37.42202, -122.08408}, } // Iterate for key, value := range m { }

Structs — no classes, just structs with methods

go · structs
type Vertex struct { X, Y float64 } var v = Vertex{1, 2} var v = Vertex{X: 1, Y: 2} // named fields var v = []Vertex{{1,2},{5,2},{5,5}} // slice of structs v.X = 4 // access members // Method with value receiver — struct is COPIED on each call func (v Vertex) Abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) } // Method with pointer receiver — struct is NOT copied (use for mutation) func (v *Vertex) add(n float64) { v.X += n v.Y += n } // Anonymous struct — cheaper than map[string]interface{} point := struct{ X, Y int }{1, 2}

Pointers — safe, no arithmetic

go · pointers
p := Vertex{1, 2} // p is a Vertex (value) q := &p // q is a *Vertex (pointer) r := &Vertex{1, 2} // r is also a *Vertex // new creates a pointer to a new zero-value instance var s *Vertex = new(Vertex)

Implicit satisfaction — no implements keyword

go · interfaces
// Interface declaration type Awesomizer interface { Awesomize() string } // Types do NOT declare to implement interfaces type Foo struct {} // Foo implicitly satisfies Awesomizer by implementing all required methods func (foo Foo) Awesomize() string { return "Awesome!" }
Duck typing in Go
Interfaces are satisfied implicitly — if a type implements all the methods an interface requires, it satisfies that interface. No implements declaration is needed. This decouples interface definitions from implementations.

No subclassing — use interface and struct embedding

go · embedding
// Interface embedding — ReadWriter must satisfy both Reader and Writer type ReadWriter interface { Reader Writer } // Struct embedding — Server exposes all Logger methods type Server struct { Host string Port int *log.Logger // embedded — field name is Logger } server := &Server{"localhost", 80, log.New(...)} server.Log(...) // calls server.Logger.Log(...) var logger *log.Logger = server.Logger // access embedded field by type name

No exceptions — errors are values

Functions that can fail return an additional error value. nil error means success.

go · error interface
type error interface { Error() string }
go · error handling pattern
func sqrt(x float64) (float64, error) { if x < 0 { return 0, errors.New("negative value") } return math.Sqrt(x), nil } func main() { val, err := sqrt(-1) if err != nil { fmt.Println(err) // "negative value" return } fmt.Println(val) }

Goroutines — lightweight threads managed by Go

go · goroutines
func doStuff(s string) { } func main() { go doStuff("foobar") // named function as goroutine go func(x int) { // anonymous function as goroutine // function body }(42) }

Channels — typed, synchronised communication

go · channels
ch := make(chan int) // unbuffered channel of int ch <- 42 // send value to channel v := <-ch // receive value from channel // Buffered channel — write doesn't block if buffer not full ch := make(chan int, 100) close(ch) // close channel (only sender should close) v, ok := <-ch // ok is false if channel is closed // Read until closed for i := range ch { fmt.Println(i) } // select — blocks on multiple channels, executes first that unblocks func doStuff(out, in chan int) { select { case out <- 42: fmt.Println("wrote to out") case x := <-in: fmt.Println("read from in") case <-time.After(time.Second * 1): fmt.Println("timeout") } }

Channel Axioms

🔴
Send to nil channel → blocks forever
var c chan string c <- "Hello" // fatal error: all goroutines are asleep — deadlock!
🔴
Receive from nil channel → blocks forever
var c chan string fmt.Println(<-c) // fatal error: deadlock!
💥
Send to closed channel → panics
var c = make(chan string, 1) c <- "Hello" close(c) c <- "Panic!" // panic: send on closed channel
Receive from closed channel → returns zero value immediately
var c = make(chan int, 2) c <- 1; c <- 2; close(c) for i := 0; i < 3; i++ { fmt.Printf("%d ", <-c) } // Output: 1 2 0 (0 is the zero value for int)

fmt package — Printf, Println, Sprintf

go · fmt printing
fmt.Println("Hello, 你好, नमस्ते, Привет, ᎣᏏᏲ") // basic print + newline p := struct{ X, Y int }{17, 2} fmt.Println("Point:", p, "x=", p.X) // print structs, ints, etc. s := fmt.Sprintln("Point:", p, "x=", p.X) // print to string variable // C-style format verbs fmt.Printf("%d hex:%x bin:%b fp:%f sci:%e", 17, 17, 17, 17.0, 17.0) s2 := fmt.Sprintf("%d %f", 17, 17.0) // Multi-line string literal with back-tick hellomsg := ` "Hello" in Chinese is 你好 ('Ni Hao') "Hello" in Hindi is नमस्ते ('Namaste') `

Type Switch — dispatch on the type held by an interface

go · type switch
func do(i interface{}) { switch v := i.(type) { case int: fmt.Printf("Twice %v is %v\n", v, v*2) case string: fmt.Printf("%q is %v bytes long\n", v, len(v)) default: fmt.Printf("Unknown type %T\n", v) } } func main() { do(21) // Twice 21 is 42 do("hello") // "hello" is 5 bytes long do(true) // Unknown type bool }
Further reading
See a8m/reflect-examples ↗ on GitHub for a comprehensive collection of Go reflection examples.

Files Embedding — static assets with the embed package

go · //go:embed — file server
package main import ( "embed" "log" "net/http" ) // Embed two static files into the binary //go:embed a.txt b.txt var content embed.FS func main() { http.Handle("/", http.FileServer(http.FS(content))) log.Fatal(http.ListenAndServe(":8080", nil)) }

HTTP Server — implementing http.Handler

go · http server
package main import ( "fmt" "net/http" ) type Hello struct{} // Hello satisfies http.Handler by implementing ServeHTTP func (h Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello!") } func main() { var h Hello http.ListenAndServe("localhost:4000", h) } // http.Handler interface signature: // type Handler interface { // ServeHTTP(w http.ResponseWriter, r *http.Request) // }
Go Language Cheat Sheet · Complete annotated reference
Code examples adapted from A Tour of Go ↗ · Click operators or copy buttons
Go Goroutines Channels Interfaces
Menu