All parts · this is part 1
- 1.Introduction to Go
- 2.Constants, Variables and Basic Data Types
- 3.Functions and Control Structures
- 4.Arrays, Slices, Maps and Loops
- 5.Strings, Runes and Bytes
- 6.Structs and Interfaces
- 7.Pointers
- 8.Goroutines
- 9.Channels
- 10.Generics
- 11.Building an API
Extras
Static and strong typing
First thing to know: Go is statically typed. When you make a variable, you either tell Go what type it is, or you give it a value right away so Go can figure it out. Either way, once it's set, that type is locked in. Want a different type? You have to convert it yourself (more on that in part 2).
Go is also strongly typed, which means what you can do with a variable depends on its type. So you can't add an int and a string together. JavaScript will happily let you do 1 + "2" and hand you back "12". Go just says no.
package main
import "fmt"
func main() {
var myVariable string = "hello" // the type, written out
inferred := "hello" // the type, worked out from the value
fmt.Println(myVariable, inferred)
// myVariable = 42 // won't compile: 42 isn't a string
// fmt.Println(inferred + 1) // won't compile: can't add a string and an int
}People mix these two up all the time, so here's the quick version. Static vs dynamic is about when types get checked: before your code runs, or while it's running. Strong vs weak is about how picky the checks are. Python is dynamic but pretty strong. C is static but lets you get away with a lot.
Practice
- Practice with AI
Warm-upWhat type is it?
What type does Go give each of these, or does it not compile at all? var a = 3, var b = 3.0, c := "3", var d int = "3".
Compiled, fast, and built for concurrency
Go is compiled. The compiler turns your code into machine code and spits out a single binary you can just run. No interpreter, nothing extra to install on the machine you run it on. Python, on the other hand, is interpreted, so it's translating your code line by line while it runs, and that adds up.
How much does it add up? In the video I counted to 100 million in both. Python took about 6 seconds on my machine, and Go took about 50 milliseconds. Here's the code if you want to try it yourself:
package main
import (
"fmt"
"time"
)
func main() {
start := time.Now()
count := 0
for i := 0; i < 100_000_000; i++ {
count++
}
fmt.Println(count, "in", time.Since(start))
}A few other things Go has going for it:
| Feature | Why you care |
|---|---|
| Fast compile times | You can write some code, compile it and test it pretty much right away. No waiting around. |
| Concurrency built in | Goroutines and channels are part of the language, no extra packages needed. We get into these in parts 8 and 9. |
| Garbage collection | Memory you're done with gets freed up for you, so it's not something you have to manage yourself. |
| Simplicity | The language is pretty small, so you can do a lot without writing a ton of code, and other people's Go is usually easy to read. |
Installing Go
The easiest way to get Go is to head to go.dev/doc/install and pick your platform. On Mac and Windows you just download the installer and run it. On Linux you unpack a file and add Go to your PATH.
To check it worked, run this in a terminal:
$ go version
go version go1.24.4 darwin/arm64If you get something like that, we're good to go.
As for an editor, use whatever you want: VS Code with the Go extension, GoLand, Vim, Neovim (that's what I use). Just make sure it's hooked up to gopls, Go's language server, so you get autocomplete and errors as you type.
Modules and packages
Before we write any code, there are two things to know about how Go code is organized: packages and modules.
- A package is just a folder with some
.gofiles in it. Every file in that folder starts with the samepackageline. - A module is a bunch of packages together. When you start a new project, you're really starting a new module.
So let's make one. Make a folder, cd into it, and run go mod init with your module's name:
$ mkdir go-tutorials && cd go-tutorials
$ go mod init github.com/you/go-tutorialsYou can call it whatever you want, but usually it's named after where it lives on GitHub, since that's how other people would import it. This creates a go.mod file:
module github.com/you/go-tutorials
go 1.24Right now it's just the module name and the Go version. Once we start installing other people's packages, they'll show up in here too, with their versions (we do that in part 11). Here's how we'll lay things out for now:
go-tutorials/
├── go.mod the module: its name and Go version
└── cmd/
└── tutorial_1/ a package (a folder of .go files)
└── main.goTo import one of your own packages, you use the module name plus the folder it's in. So if we add a greetings package, main imports it like this:
// greetings/greetings.go
package greetings
// Hello starts with a capital letter, so other packages can call it.
func Hello(name string) string {
return "Hello, " + name
}
// cmd/tutorial_1/main.go
package main
import (
"fmt"
"github.com/you/go-tutorials/greetings"
)
func main() {
fmt.Println(greetings.Hello("Gopher"))
}Practice
- Practice with AI
PracticeAdd your own package
The template has a main.go and a mathutil package. Fill in Double(n int) int so main prints 42. Then main also calls mathutil.triple(14), which doesn't compile: fix the mathutil package so it does, and say why it didn't.
Your first program
Time to write some code. Make a main.go file in cmd/tutorial_1:
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}So what's going on here?
package mainis a special package name. It tells the compiler "this is a program, start here".- The compiler then looks for a function called
mainin that package, and that's the first thing that runs. This only applies tomain, by the way. If you had a package calledblue, you wouldn't need a function calledblue. import "fmt"pulls in Go's built-in formatting package, andfmt.Printlnprints whatever you give it plus a new line.- The opening curly brace has to be on the same line as
func main(). Put it on the next line and you get an error.
Practice
- Practice with AI
PracticeFix it
This program won't run: it says package app at the top, imports fmt and os, and has func Main(). Find all three problems and fix them.
- Practice with AI
Warm-upHello, you
The template reads your name and your favorite language. Print the name on one line and the language on the next with fmt.Println.
go build and go run
Now let's run it. You've got two options:
go build cmd/tutorial_1/main.go # writes a binary called main
./main # runs it: Hello, World!
go run cmd/tutorial_1/main.go # compiles to a temporary binary and runs it
go build -o hello ./cmd/tutorial_1 # name the binary yourselfgo build gives you a binary you can run whenever you want. go run does the build and the run in one command, and honestly it's what I use most of the time while I'm working on something.
Since the binary has everything it needs baked in, you can copy it to another machine with the same OS and it'll just run. You can even build for a different OS than the one you're on. Here's building a Linux binary from a Mac:
GOOS=linux GOARCH=amd64 go build -o hello-linux ./cmd/tutorial_1And that's it, you just wrote and ran your first Go program. Pretty cool.