Why Learn Go?
Go is built for the modern cloud
Created at Google in 2009, Go (Golang) is designed for building fast, reliable, and efficient software. It powers Docker, Kubernetes, Terraform, and most of the cloud-native ecosystem.
Go sits in a sweet spot: it's as fast as C/C++ for most workloads, but as easy to write as Python. It compiles to a single binary with no dependencies, making deployment trivial. Its built-in concurrency model (goroutines and channels) makes it perfect for servers, APIs, and distributed systems.
Cloud & DevOps
Docker, Kubernetes, Terraform, Prometheus — the cloud-native stack runs on Go.
Blazing Fast
Compiled to native code. No VM, no interpreter. Starts in milliseconds, uses minimal memory.
Simple by Design
25 keywords. No classes, no inheritance, no exceptions. Simplicity is Go's superpower.
Built-in Concurrency
Goroutines and channels make concurrent programming natural and safe.
Installing Go
Go has a simple installation process. Download the binary, add it to your PATH, and you're ready.
macOS
# Using Homebrew
brew install go
# Verify
go version
go version go1.22.2 darwin/arm64
Linux
# Download and extract
wget https://go.dev/dl/go1.22.2.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.22.2.linux-amd64.tar.gz
# Add to PATH (add to ~/.bashrc or ~/.zshrc)
export PATH=$PATH:/usr/local/go/bin
go version
Windows
Download the MSI installer from go.dev/dl and run it. Go is automatically added to PATH.
Your First Go Program
Let's create the classic "Hello, World!" but with a twist — we'll also demonstrate Go's strict typing and formatting.
Create a Module
Every Go project starts with a module. A module is a collection of packages with a go.mod file:
mkdir hello && cd hello
go mod init hello
Write main.go
package main
import "fmt"
func main() {
// Variables with type inference
name := "Gopher"
age := 1
// Formatted output
fmt.Printf("Hello, %s! You are %d day(s) into Go.\n", name, age)
// Multiple return values (a Go specialty)
sum, product := calculate(3, 4)
fmt.Printf("3+4=%d, 3*4=%d\n", sum, product)
}
func calculate(a, b int) (int, int) {
return a + b, a * b
}
go run main.go
Hello, Gopher! You are 1 day(s) into Go. 3+4=7, 3*4=12
Key things to notice: package main and func main() are the entry point. := declares and assigns a variable with type inference. Functions can return multiple values. Unused imports and variables are compile errors — Go enforces clean code.
Go Modules
Go modules manage dependencies. The go.mod file tracks your module name and dependency versions:
# Initialize a module
go mod init github.com/yourname/myproject
# Add a dependency (automatically when you import it)
go get github.com/gin-gonic/gin
# Tidy up (remove unused, add missing)
go mod tidy
# View dependencies
cat go.mod
No node_modules, no virtualenv
Go downloads dependencies to a shared cache ($GOPATH/pkg/mod) and uses checksums (go.sum) to ensure integrity. No per-project duplication. No dependency hell.
IDE Setup
| Editor | Plugin | Features |
|---|---|---|
| VS Code | Go extension (official) | Autocomplete, debugging, testing, formatting |
| GoLand | Built-in | Full IDE, refactoring, profiling |
| Vim/Neovim | vim-go or gopls | LSP, formatting, testing |
# Format your code (Go has ONE standard style)
go fmt ./...
# Run tests
go test ./...
# Build a binary
go build -o myapp
go fmt), one way to manage dependencies (go mod), and one way to test (go test). No debates, no configuration. Just code.🔍 Deep Dive: go fmt and goimports
go fmt automatically formats your code to Go's standard style. There's no configuration — all Go code looks the same. goimports goes further: it also adds missing imports and removes unused ones. Most IDEs run these on save. This eliminates all formatting debates on teams.
⚠️ Common Mistake: Unused Variables
Wrong:
x := 42 // Declared but never used
// main.go:5:2: x declared and not used (compile error!)
Why: Go refuses to compile code with unused variables or imports. This is intentional — it prevents dead code from accumulating.
Instead: Use _ to explicitly discard values you don't need: _, err := doSomething()
Fast compile, simple, concurrent
Easy syntax, slow runtime
Verbose, JVM overhead
Memory safe, steep learning
Fastest, manual memory
Async I/O, single thread
Practice Exercises
Easy Hello World Variant
Modify the example to accept user input and print a personalized greeting.
Easy Code Reading
Read through the code examples above and predict the output before running them.
Medium Extend the Example
Take one code example and add error handling, input validation, or a new feature.