Go Fundamentals Basics
10 examples to get you started with Go Fundamentals - 7 basic and 3 intermediate.
Search across all documentation pages
10 examples to get you started with Go Fundamentals - 7 basic and 3 intermediate.
mkdir hello && cd hello && go mod init example.com/hello.go run . after saving it as main.go in that directory.The smallest executable: a main package with func main().
package main
import "fmt"
func main() {
fmt.Println("hello, Go")
}package main marks an executable, not a library.import "fmt" brings in the formatted I/O package from the standard library.go run . compiles and runs without leaving a binary in the directory.Related: How Go Programs Are Structured - packages, linking, and the toolchain
Declare with var or use := inside functions.
package main
import "fmt"
func main() {
var name string = "Go"
year := 2009
fmt.Println(name, year)
}:= infers type and can only appear inside functions.var works at package level; := does not.Related: Variables, Constants & Scope - declaration styles and scope rules
Variables get a default without explicit initialization.
package main
import "fmt"
func main() {
var count int
var ready bool
var label string
fmt.Printf("int=%d bool=%t string=%q\n", count, ready, label)
}0, bool to false, strings to "".nil.Related: Zero Values and Initialization - per-type defaults and init patterns
const names compile-time values; iota builds enumerated constants.
package main
import "fmt"
const (
Sunday = iota
Monday
Tuesday
)
func main() {
fmt.Println(Sunday, Monday, Tuesday) // 0 1 2
}iota resets to 0 in each const block and increments per line.Related: Variables, Constants & Scope -
iotapatterns and scope
Strings are UTF-8 byte sequences; iterate by rune with range.
package main
import "fmt"
func main() {
s := "café"
for i, r := range s {
fmt.Printf("%d: %U\n", i, r)
}
}range over a string yields byte index and rune (int32), not byte offset for multi-byte chars.len(s) counts bytes, not runes.[]rune(s) when you need random access by character index.Related: Numeric Types, Strings, Runes & Byte Slices - UTF-8, runes, and conversions
Slices are dynamic views over an underlying array.
package main
import "fmt"
func main() {
nums := []int{1, 2, 3}
nums = append(nums, 4)
fmt.Println(nums, len(nums), cap(nums))
}append may allocate a new backing array when capacity is exceeded.len is element count; cap is backing array size from the slice header.nil slice is valid and works with append and range.Related: Arrays, Slices & Maps at a Glance - len/cap and sharing
Maps are hash tables keyed by comparable types.
package main
import "fmt"
func main() {
ages := map[string]int{"ada": 36}
ages["linus"] = 55
if v, ok := ages["grace"]; ok {
fmt.Println(v)
} else {
fmt.Println("grace: unknown")
}
}v, ok := m[key] distinguishes missing keys from zero values.make or a literal before assignment.Related: Arrays, Slices & Maps at a Glance - map iteration and gotchas
Group fields in a struct; embed to promote methods and fields.
package main
import "fmt"
type Person struct{ Name string }
type Employee struct {
Person
ID int
}
func main() {
e := Employee{Person: Person{Name: "Grace"}, ID: 1}
fmt.Println(e.Name, e.ID) // promoted field
}Related: Structs, Embedding & Field Promotion - modeling and promotion rules
& takes an address; * dereferences. Methods can use pointer receivers to mutate.
package main
import "fmt"
type Counter struct{ n int }
func (c *Counter) Inc() { c.n++ }
func main() {
c := &Counter{}
c.Inc()
fmt.Println(c.n)
}nil pointers panic on dereference - check before use.Related: Pointers & the Address-of Operator - when pointers help vs hurt
Split main from reusable code across packages in one module.
// main.go
package main
import "example.com/hello/greet"
func main() {
greet.Hello("world")
}// greet/greet.go
package greet
import "fmt"
func Hello(name string) {
fmt.Printf("hello, %s\n", name)
}main packages build executables; greet is a library package.Hello); lowercase stays private.go run . with both files in place.Related: How Go Programs Are Structured - modules, imports, and
internal/
Stack versions: This page was written for Go 1.26.x (Green Tea GC default, go fix modernizers - verify patch at build), chi (latest - verify at build), gin (latest - verify at build), echo (latest - verify at build), google.golang.org/grpc (latest - verify at build), sigs.k8s.io/controller-runtime (latest - verify at build), kubebuilder (latest - verify at build), tinygo (latest - verify board targets at build), wazero (latest - verify at build), and golangci-lint (latest - verify linter set at build).
Reviewed by Chris St. John·Last updated Jul 19, 2026