Part 2 -- Installation & Getting Ready to Build¶
Installing Go¶
Option 1: MSI Installer (Recommended)
- Download the latest installer from go.dev/dl
- Run the
.msiinstaller - Go installs to
C:\Program Files\Goby default - The installer adds
C:\Program Files\Go\binto yourPATHautomatically
Option 2: Winget
Option 3: Chocolatey
Verify installation:
Option 1: Homebrew (Recommended)
Option 2: Official Installer
- Download the
.pkgfrom go.dev/dl - Run the installer
- Go installs to
/usr/local/go
Verify installation:
Option 1: Official Tarball (Recommended)
# Download (check go.dev/dl for latest version)
wget https://go.dev/dl/go1.22.2.linux-amd64.tar.gz
# Remove any previous installation and extract
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.22.2.linux-amd64.tar.gz
# Add to PATH (add to ~/.bashrc or ~/.zshrc for persistence)
export PATH=$PATH:/usr/local/go/bin
Option 2: Snap
Verify installation:
Understanding Go's Environment¶
Key Environment Variables¶
| Variable | Default | Purpose |
|---|---|---|
GOROOT |
Where Go is installed | Location of the Go SDK. Rarely needs changing. |
GOPATH |
$HOME/go (or %USERPROFILE%\go) |
Where Go stores downloaded modules and built binaries |
GOBIN |
$GOPATH/bin |
Where go install places compiled binaries |
GOPROXY |
https://proxy.golang.org,direct |
Module proxy for downloading dependencies |
GOMODCACHE |
$GOPATH/pkg/mod |
Cache for downloaded module source code |
Check your current environment:
Check specific variables:
The GOPATH Directory Structure¶
$GOPATH/
├── bin/ # Compiled binaries from 'go install'
├── pkg/
│ └── mod/ # Downloaded module source code (module cache)
└── src/ # (Legacy) Before modules, source code lived here
Common Mistake
With Go modules (Go 1.11+), you do not need to work inside GOPATH. You can create projects anywhere on your filesystem. The GOPATH/src layout is legacy.
Editor Setup¶
- Install Visual Studio Code
- Install the Go extension by the Go Team at Google:
- Open VS Code → Extensions → Search "Go" → Install the one by "Go Team at Google"
- Open any
.gofile -- VS Code will prompt to install Go tools. Click Install All.
This installs:
| Tool | Purpose |
|---|---|
gopls |
Language server (IntelliSense, navigation, refactoring) |
dlv |
Debugger (delve) |
staticcheck |
Advanced linter |
gotests |
Test generation |
goplay |
Playground integration |
Recommended VS Code Settings (.vscode/settings.json):
- Download GoLand (paid, 30-day trial)
- Install and open
- GoLand auto-detects your Go installation
- Everything works out of the box -- debugger, test runner, profiler, database tools
GoLand is the most feature-rich Go IDE but requires a JetBrains license.
| Editor | Go Support |
|---|---|
| Neovim | gopls via LSP + nvim-lspconfig |
| Sublime Text | LSP package + gopls |
| Emacs | lsp-mode + gopls |
| Vim | vim-go plugin or gopls via CoC |
Your First Go Program¶
Step 1: Create a Project¶
# Create a directory anywhere on your filesystem
mkdir hello-go
cd hello-go
# Initialize a Go module
go mod init hello-go
This creates a go.mod file:
Step 2: Write Code¶
Create main.go:
Step 3: Run It¶
# Compile and run in one step
go run main.go
# Output: Hello, Go!
# Or build a binary first, then run it
go build -o hello .
./hello
# Output: Hello, Go!
Understanding the Code¶
| Element | Meaning |
|---|---|
package main |
This file belongs to the main package -- the entry point for executables |
import "fmt" |
Import the fmt (format) package from the standard library |
func main() |
The main function in the main package is where execution begins |
fmt.Println() |
Print a line to stdout with a newline |
Key Rule
Every Go executable must have a package main with a func main(). Library packages use different names and don't have main().
Essential Go Commands¶
Build & Run¶
go run main.go # Compile and run
go run . # Compile and run entire package
go build # Build binary (same name as module)
go build -o myapp . # Build binary with custom name
go install # Build and install to $GOBIN
Modules & Dependencies¶
go mod init myproject # Initialize a new module
go mod tidy # Add missing, remove unused dependencies
go get github.com/pkg/lib # Add a dependency
go get -u ./... # Update all dependencies
go mod vendor # Copy dependencies into vendor/
go mod download # Pre-download dependencies (for Docker builds)
Testing¶
go test ./... # Run all tests in all packages
go test -v ./... # Verbose output
go test -run TestName ./... # Run specific test
go test -race ./... # Run with race detector
go test -cover ./... # Show coverage percentage
go test -bench=. ./... # Run benchmarks
Code Quality¶
go fmt ./... # Format all code (canonical style)
go vet ./... # Static analysis for bugs
golangci-lint run # Run multiple linters (install separately)
Information¶
go doc fmt.Println # View documentation for a symbol
go env # Print all Go environment variables
go version # Print Go version
go list -m all # List all dependencies
Project Structure Conventions¶
Go doesn't enforce a project structure, but the community follows a standard layout:
Small Project (CLI Tool / Library)¶
myproject/
├── go.mod
├── go.sum
├── main.go # Entry point (for executables)
├── handler.go # Other source files in the same package
├── handler_test.go # Test files end in _test.go
└── README.md
Medium Project (API Service)¶
myproject/
├── cmd/
│ └── server/
│ └── main.go # Entry point
├── internal/ # Private packages (not importable by others)
│ ├── handler/
│ │ ├── handler.go
│ │ └── handler_test.go
│ ├── service/
│ │ └── service.go
│ └── repository/
│ └── repository.go
├── pkg/ # Public packages (importable by others)
│ └── models/
│ └── models.go
├── go.mod
├── go.sum
├── Dockerfile
└── README.md
Large Project (Multiple Services)¶
myproject/
├── cmd/
│ ├── api-server/
│ │ └── main.go
│ ├── worker/
│ │ └── main.go
│ └── cli/
│ └── main.go
├── internal/
│ ├── api/
│ ├── worker/
│ └── shared/
├── pkg/
│ ├── models/
│ └── client/
├── proto/ # Protocol buffer definitions
├── scripts/ # Build/deploy scripts
├── deployments/ # Docker, Kubernetes configs
├── go.mod
├── go.sum
├── Makefile
└── README.md
Interview Insight
The internal/ directory is special in Go. Packages under internal/ can only be imported by code within the parent of internal/. This is enforced by the compiler, making it the only visibility mechanism beyond exported/unexported identifiers. Mentioning this in interviews shows you understand Go's module system deeply.
Installing Additional Tools¶
# Install golangci-lint (meta-linter)
go install github.com/golangci-lint/golangci-lint/cmd/golangci-lint@latest
# Install delve debugger
go install github.com/go-delve/delve/cmd/dlv@latest
# Install mockgen (for generating mocks)
go install go.uber.org/mock/mockgen@latest
# Install protoc-gen-go (for Protocol Buffers)
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
Verifying Everything Works¶
Run this checklist after installation:
# 1. Go is installed
go version
# 2. Environment is correct
go env GOPATH GOROOT
# 3. Can create and run a program
mkdir -p /tmp/gotest && cd /tmp/gotest
go mod init test
echo 'package main; import "fmt"; func main() { fmt.Println("Ready!") }' > main.go
go run main.go
# 4. Tests work
echo 'package main; import "testing"; func TestOK(t *testing.T) {}' > main_test.go
go test -v
# 5. Formatting works
go fmt ./...
# 6. Vet works
go vet ./...
If all commands succeed, you're ready to start building with Go.