Setup, your first program, and the toolchain
Install Go, run one file, and meet the four commands you will use every day.
- Write and run a
package mainprogram withgo run .. - Explain what the zero value of an
int, astringand aboolis. - Predict what
go build,go fmtandgo veteach do before you run them.
Go is a compiled language. You write a .go file, the compiler turns it into a single machine-code binary, and you run that. There is no interpreter to install on the server and no virtual machine. That one fact explains most of what people like about Go: you build one file and copy it anywhere.
First, install it. Pick your system below. Every option installs the same thing: the compiler, the standard library and the go command.
go version# go version go1.25.1 linux/amd64Install Go
# with Homebrew (easiest)brew install go# or download the .pkg installer from https://go.dev/dl/# and double-click it# with wingetwinget install GoLang.Go# or download the .msi installer from https://go.dev/dl/# then close and reopen your terminal so PATH updates# the official way — distribution packages are often far behindcurl -LO https://go.dev/dl/go1.25.1.linux-amd64.tar.gzsudo rm -rf /usr/local/gosudo tar -C /usr/local -xzf go1.25.1.linux-amd64.tar.gz# then add Go to your PATH, and reload your shellecho 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profilesource ~/.profilego version# go version go1.25.1 linux/amd64go env GOPATH# /home/you/go — where downloaded packages live. You rarely need to touch it.go command does all of it.You can also run Go without installing anything
Every code block on this site with a ▶ Run button executes on the official Go Playground, so you can work through the language topics in a browser before you install anything. Press Run, change the code, press Run again.
You will need a real installation from the practice projects onwards, because those use files, folders and a database. The playground has none of them.
A module is a project
Every Go project is a module. A module is a folder with a go.mod file at the top. That file records the module name and which Go version it needs. You make one once, at the start.
mkdir -p ~/go-learn/d01cd ~/go-learn/d01go mod init d01The first program
Every Go file starts with package. A program you can run lives in package main and has a func main(). That function is where execution starts, and when it returns the program exits.
package mainimport "fmt"func main() { fmt.Println("hello") name := "sahdev" // short declaration, the type is inferred var age int = 25 // the long form, type written out var city string // no value given, so it gets the zero value: "" const pi = 3.14 // fixed at compile time, cannot change fmt.Println(name, age, city, pi)}Three ways to declare, one you will mostly use
name := "sahdev"— inside a function, the common case. Go works out the type.var age int = 25— when you want the type written down, or you are outside a function.var city string— declare now, assign later. It holds the zero value until you do.const pi = 3.14— a value fixed at compile time. It cannot be changed and has no address.
Zero values: Go has no "undefined"
This is the first idea that makes Go different from JavaScript or Python. A variable you declare but do not set is not empty, null, or undefined. It holds a well-defined zero value for its type.
| Type | Zero value |
|---|---|
int, float64 | 0 |
string | "" (empty, not nil) |
bool | false |
Because of this you never get a "cannot read property of undefined" style crash from an unset variable. The other types you will meet later also have zero values, and each lesson says what they are.
The four commands
go run . # compile and run, leave no binary behindgo build -o app . # produce ./app, ready to copy to a servergo fmt ./... # format the code. Not a preference, the standard.go vet ./... # find real mistakes the compiler allowsgo fmt applies it. Tabs, brace placement and spacing are decided for you, so a Go team has nothing to argue about there. Most editors run it on save; if yours does not, run it before every commit.Try it yourself
package mainimport "fmt"func main() { name := "sahdev" // short declaration, the type is inferred var age int = 25 // the long form, type written out var city string // never assigned, so it holds the zero value const pi = 3.14 // fixed at compile time fmt.Println(name, age, city, pi) fmt.Printf("city is %q and has %d characters\n", city, len(city))}Build this: your first win
A tiny program that does a real job: split a bill. Put it in main.go in your d01 folder and run go run .. Then change the numbers and run it again.
package mainimport "fmt"func main() { total := 84.50 people := 4 share := total / float64(people) fmt.Println("Total:", total) fmt.Println("People:", people) fmt.Println("Each pays:", share)}- A module is a folder with a
go.mod. A runnable program ispackage mainwithfunc main(). - Every variable has a zero value. There is no undefined, and no unset variable to guard against.
:=inside functions,varwhen you want the type written down or you are at package level.go run,go build,go fmt,go vet. That is the whole daily toolchain.
- 1Make a second file in the same folder, put a function in it, and call that function from
main. Notice you did not need an import. - 2Delete the
fmtimport while still callingfmt.Println, and read the error. Then add an unused variable and read that one too. - 3Build with
go build -o app .and run./app. Copy the binary to another folder and run it there — nothing else needed.