Go by Contrast
Slices, maps & the standard library
Lesson 5 of 5
What you'll learn
- Understand slices (the growable view) vs fixed-size arrays
- Use maps as Go's typed key-value structure
- Appreciate the batteries-included standard library ethos
A Go array has a fixed length baked into its type: [3]int is a different type from [4]int. You almost never use them directly. Instead you use a slice — a growable, resizable view over an underlying array, written []int. This is the day-to-day "list" type and behaves much like a JS array.
nums := []int{1, 2, 3}
nums = append(nums, 4) // returns a (possibly new) slice
fmt.Println(nums, len(nums)) // [1 2 3 4] 4
In TypeScript that's just an array with push:
const nums: number[] = [1, 2, 3];
nums.push(4);
console.log(nums, nums.length); // [1,2,3,4] 4
One gotcha: append may allocate a new backing array when the slice grows past its capacity, so you must assign the result back — nums = append(nums, 4). There's no in-place push that mutates and returns nothing.
Maps
A map is Go's hash table: map[K]V. Keys and values are both typed, unlike a JS object (string/symbol keys only) or even a JS Map.
counts := map[string]int{}
counts["go"]++ // missing key reads as the zero value, 0
val, ok := counts["go"] // ok is false if the key was absent
fmt.Println(val, ok) // 1 true
The value, ok := form is how you distinguish "present with zero value" from "absent" — there's no undefined.
Batteries included
Go's standard library is famously complete: an HTTP server, JSON encoding, crypto, templating, testing, and more all ship in the box, with a stable API. That ethos — plus a single static binary and fast compiles — is exactly why Kubernetes, Docker, and Terraform are written in Go. Platform tooling values "clone, go build, ship one binary" over a sprawling dependency tree.
import (
"encoding/json"
"net/http"
)
// json.Marshal, http.ListenAndServe — no third-party install needed.
The stdlib is the framework
Where a Node service might pull in Express, dotenv, and a dozen utilities, idiomatic Go reaches for net/http, encoding/json, and flag from the standard library first. Fewer dependencies, fewer surprises.
The challenge is a JS model of two everyday Go moves: growing a slice with append, and counting words into a map.
Run it. This models Go's append-and-reassign on a slice and a map[string]int word counter.
That's the tour: types and structs, errors as values, implicit interfaces, goroutines and channels, and a stdlib built for shipping platform tools. You can now read most Go you'll meet in cloud-native codebases.
Why must you assign the result of append back to the slice variable?
Saved on this device. Sign in to sync your progress everywhere.