1. What is Go?
Go is an open-source programming language from Google. It helps developers build simple and reliable software. Google released Go as open source in 2009.
Full lesson: Go intro
41 questions about Go with short answers and code. Each answer links to a full lesson on this site. Free, with no signup and no ads.
Go is an open-source programming language from Google. It helps developers build simple and reliable software. Google released Go as open source in 2009.
Full lesson: Go intro
Call fmt.Println inside the main function. Each Go statement ends at the line break. You do not need a semicolon.
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
Full lesson: Go basic syntax
Use the var keyword, then the name, then the type. You can declare many variables on one line.
var a string = "Example"
var b, c int = 1, 2
fmt.Println(a, b, c)
Full lesson: Go variables
Go provides bool, numeric types, string, and derived types. Numeric types include int, float32, and float64. A bool value is only true or false.
var b bool = true
var n int = 10
var f float64 = 3.5
Full lesson: Go data types
Go runs the block when the boolean expression is true. Go skips the block when the expression is false. The braces are always required.
var a int = 10
if a < 20 {
fmt.Println("a is less than 20")
}
Full lesson: Go if statement
Go has three forms of the for loop. One form uses init, condition, and post. Another form works like a while loop.
for i := 0; i < 3; i++ {
fmt.Println(i)
}
Full lesson: Go for loop
Give the size and the element type. The index starts at 0. You can read or change each element by index.
var numbers [3]int
numbers[0] = 5
fmt.Println(numbers[0])
Full lesson: Go arrays
Use the func keyword, then the name, parameters, and return type. Every Go program has at least one main function. Each function does one task.
func add(a int, b int) int {
return a + b
}
Full lesson: Go functions
Write the target type before the value in parentheses. Go needs an explicit conversion for different numeric types. The conversion can cut data when the target type is smaller.
var i int = 42
var f float64 = float64(i)
fmt.Println(f)
Full lesson: Go type casting
A map stores key and value pairs. Use make to create a map. Read a value with the key in brackets.
m := make(map[string]int)
m["one"] = 1
fmt.Println(m["one"])
Full lesson: Go map
The range keyword gives the index and the value on each step. Use an underscore to skip the index. Range also works on strings and channels.
nums := []int{10, 20}
for i, v := range nums {
fmt.Println(i, v)
}
Full lesson: Go range
An interface lists method signatures. A type implements the interface when it has all these methods. Go needs no keyword for this, so the link is implicit.
type Shape interface {
Area() float64
}
Full lesson: Go interfaces
Go returns errors as normal values. Check the error value after each call. Return the error to the caller when it is not nil.
f, err := os.Open("data.txt")
if err != nil {
return err
}
defer f.Close()
Full lesson: Go error handling
A type assertion gets the concrete value from an interface. The two-value form returns the value and a boolean. Use the boolean to test the type in a safe way.
var x interface{} = "hi"
s, ok := x.(string)
fmt.Println(s, ok)
Full lesson: Go type assertion
The variable i is declared but never used. Go reports an error for unused local variables. Use the variable or remove it.
// wrong
func main() {
i := 5
}
Full lesson: Go variables
The closure captures the loop variable, not its value. All closures share the same variable. Pass the value as a parameter or copy it inside the loop.
// wrong
for _, v := range []int{1, 2} {
go func() { fmt.Println(v) }()
}
Full lesson: Go function closures
A Go module is a collection of Go packages. The go.mod file defines the module path and its dependencies.
module example.com/mymodule
go 1.20
Full lesson: Go modules
You place one for loop inside another for loop. The inner loop runs completely for each iteration of the outer loop.
for i := 0; i < 3; i++ {
for j := 0; j < 2; j++ {
fmt.Println(i, j)
}
}
Full lesson: Go nested loops
You declare the parameter as an array with a fixed size. Go copies the array when you pass it to a function.
func sum(a [3]int) int {
return a[0] + a[1] + a[2]
}
Full lesson: Go passing arrays to functions
An anonymous function is a function without a name. You can define it inline and use it as a closure.
add := func(x, y int) int {
return x + y
}
fmt.Println(add(3, 5))
Full lesson: Go function closures
The select statement waits on multiple channel operations. It runs the case for the first channel that is ready.
select {
case msg := <-ch1:
fmt.Println(msg)
case ch2 <- 10:
fmt.Println("sent")
}
Full lesson: Go select statement
You can use os.Open to open the file and bufio.Scanner to read it line by line. Always close the file with defer.
f, _ := os.Open("file.txt")
defer f.Close()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
Full lesson: Go file handle
Go does not have classes or inheritance. It uses struct embedding and interfaces to reuse code and achieve polymorphism.
type Animal struct{}
func (a Animal) Speak() { fmt.Println("...") }
type Dog struct{ Animal }
Full lesson: Go inheritance
You can use Visual Studio Code with the Go extension, GoLand, or LiteIDE. These tools provide code hints, testing, and debugging.
Full lesson: Go ide
When you access a missing key, Go returns the zero value for the map's value type. For int it is 0, and for string it is an empty string.
m := map[string]int{}
fmt.Println(m["missing"]) // prints 0
Full lesson: Go map
Use the two-value form of type assertion. The second value is a boolean that reports whether the assertion succeeded.
v, ok := i.(string)
if ok {
fmt.Println(v)
}
Full lesson: Go type assertion
Go does not allow implicit conversion between numeric types. You must convert x to float64 explicitly.
var x int = 10
var y float64 = float64(x)
Full lesson: Go type casting
The slice s is nil and has no elements. Assigning to index 0 causes an index out of range panic. You must allocate the slice first.
s := make([]int, 1)
s[0] = 1
Full lesson: Go arrays
The goroutines share the loop variable i. They can run after the loop finishes, so they print the final value. Pass i as a parameter to capture its current value.
for i := 0; i < 3; i++ {
go func(n int) { fmt.Println(n) }(i)
}
Full lesson: Go for loop
Arrays are value types in Go. The function receives a copy of the array, so changes do not affect the original. Pass a pointer to modify the original array.
func modify(a *[3]int) { a[0] = 100 }
Full lesson: Go passing arrays to functions
MyInt is a distinct type, not an alias for int. You must convert x to MyInt explicitly.
var y MyInt = MyInt(x)
Full lesson: Go type casting
A map is an unordered collection of key-value pairs. You can quickly retrieve a value by its key.
m := map[string]int{"a": 1}
fmt.Println(m["a"])
Full lesson: Go map
Use the make function with the map type and a capacity. This can reduce memory allocations when you add many keys.
m := make(map[string]int, 10)
m["x"] = 1
Full lesson: Go map
Range returns the index and a copy of the value at that index. You can omit either one with an underscore.
for i, v := range []int{10, 20} {
fmt.Println(i, v)
}
Full lesson: Go range
Use range with one variable. The single variable receives the key.
for k := range m {
fmt.Println(k)
}
Full lesson: Go range
Use a slice parameter instead of an array with a fixed size. A slice parameter accepts an array or a slice.
func sum(nums []int) int {
total := 0
for _, n := range nums { total += n }
return total
}
Full lesson: Go passing arrays to functions
Go copies the whole array. Changes inside the function do not affect the original array.
func change(a [3]int) { a[0] = 9 }
Full lesson: Go passing arrays to functions
Pass a pointer to the array. The function then changes the original array.
func change(a *[3]int) { a[0] = 9 }
Full lesson: Go passing arrays to functions
Assign an anonymous function to a variable. Then call the variable like a normal function.
f := func(x int) int { return x * 2 }
fmt.Println(f(3))
Full lesson: Go function closures
A closure captures a variable from its outer function. Each call can update that captured variable.
count := func() func() int {
n := 0
return func() int { n++; return n }
}()
Full lesson: Go function closures
Add a default case to select. The default case runs when no other case is ready.
select {
case v := <-ch:
fmt.Println(v)
default:
fmt.Println("no value")
}
Full lesson: Go select statement