Go Course Code
This page features the code from our Full Go Course on YouTube. Click 'Run' to execute a code snippet, or click directly on the code to edit it.
Watch the course on YouTube at https://www.youtube.com/@codebuilds
+ Chapter 1: Variables, Data types and Basic operators
Basic Greetings
Simple greeting messages demonstrating string variables in Go
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
var agency string = "Fast Track"
fmt.Println("Welcome to", agency)
} Variable Declaration and Output
Declaring string variables and printing them using fmt.Println and fmt.Printf
package main
import "fmt"
func main() {
name := "Gopher"
fmt.Printf("Hello, %v!\n", name)
var agency = "Fast Track"
fmt.Println("Welcome to", agency)
} Integer Data Type Usage
Using integer data types to represent numerical values
package main
import "fmt"
func main() {
name := "Gopher"
fmt.Println("Hello,", name+"!")
var agency = "Fast Track"
fmt.Println("Welcome to", agency)
var totalCars int = 50
fmt.Println("Our fleet consists of", totalCars, "cars")
} Constants and Iota
Defining constants using const and iota for enumerations in Go
package main
import "fmt"
const (
Agency = "Fast Tracks"
Founded = 2001
Founder = "James Carter"
)
const (
_ = iota
Economy
Compact
Standard
FullSize
Luxury
)
func main() {
fmt.Println("Agency:", Agency)
fmt.Println("Car type:", Economy)
} String Manipulation
Basic string operations including length, comparison, and substring extraction
package main
import (
"fmt"
"strings"
)
func main() {
str := "Hello, World!"
fmt.Println("Length:", len(str))
str1 := "Go Programming"
str2 := "go programming"
fmt.Println("EqualFold:", strings.EqualFold(str1, str2))
fmt.Println("Contains 'Go':", strings.Contains(str1, "Go"))
fmt.Println("To Upper:", strings.ToUpper(str1))
fmt.Println("To Lower:", strings.ToLower(str1))
} Math Functions
Demonstrates usage of various math functions in Go
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println("Round 288.75:", math.Round(288.75))
fmt.Println("Ceil 288.75:", math.Ceil(288.75))
fmt.Println("Floor 288.75:", math.Floor(288.75))
fmt.Println("Abs -5.5:", math.Abs(-5.5))
fmt.Println("Pow 3^2:", math.Pow(3, 2))
fmt.Println("Sqrt 16:", math.Sqrt(16))
} Type Conversions
Various type conversions between integers, floats, and strings
package main
import (
"fmt"
"strconv"
)
func main() {
var tempInt int = 10
var tempFloat float64 = float64(tempInt)
fmt.Println("Integer to Float:", tempFloat)
var myFloat float64 = 9.8
var myIntFromFloat int = int(myFloat)
fmt.Println("Float to Integer:", myIntFromFloat)
var myIntToStr string = strconv.Itoa(tempInt)
fmt.Println("Integer to String:", myIntToStr)
var myStr string = "42"
var myIntFromString, _ = strconv.Atoi(myStr)
fmt.Println("String to Integer:", myIntFromString)
} Pointers
Demonstrates pointer manipulation and passing by reference
package main
import "fmt"
func sayHello(s string) {
s = "Hello, World"
}
func sayHelloPointer(s *string) {
*s = "Hello, World"
}
func main() {
var greeting string = "Hello, GO"
fmt.Println("Initial Value:", greeting)
sayHello(greeting)
fmt.Println("After sayHello:", greeting)
sayHelloPointer(&greeting)
fmt.Println("After sayHelloPointer:", greeting)
} + Chapter 2: Control Structures (if, switch, for)
Basic if statement
Simple conditional logic with if-else
package main
import "fmt"
func main() {
isFast := true
if isFast {
fmt.Println("You're going too fast, slow down!")
} else {
fmt.Println("Thank you for not speeding")
}
} Comparison operators
Using > and < operators to compare values
package main
import "fmt"
const upperSpeedLimit, lowerSpeedLimit int = 120, 80
func main() {
speed := 130
if speed > upperSpeedLimit {
fmt.Println("You're going too fast, slow down!")
} else if speed < lowerSpeedLimit {
fmt.Println("You're going too slow!")
} else {
fmt.Println("Thank you for driving within speed limits")
}
} Switch statement
Basic usage of switch statement
package main
import "fmt"
func main() {
color := "blue"
switch color {
case "red":
fmt.Println("Red: Passion and Energy")
case "green":
fmt.Println("Green: Growth and Harmony")
case "blue":
fmt.Println("Blue: Calm and Trust")
default:
fmt.Println("Unknown Color")
}
} Switch with multiple cases
Switch statement with multiple cases per branch
package main
import "fmt"
func main() {
day := "Tue"
switch day {
case "Mon", "Tue", "Wed", "Thu", "Fri":
fmt.Println("Week day")
case "Sat", "Sun":
fmt.Println("Weekend")
default:
fmt.Println("Invalid day")
}
} For loop
Demonstrates a simple for loop
package main
import "fmt"
func main() {
for i := 0; i < 5; i++ {
fmt.Println("Loop iteration:", i)
}
} Continue and Break
Using continue to skip iterations and break to exit
package main
import "fmt"
func main() {
// Skip even numbers
for j := 0; j < 10; j++ {
if j%2 == 0 {
continue
}
fmt.Println("Odd number:", j)
}
// Break example
i := 0
for {
fmt.Println("Infinite loop, iteration:", i)
i++
if i == 3 {
break
}
}
} + Chapter 3: Data structures (Arrays, Slices, Maps)
Simple Array
Declaration and usage of a simple array in Go
package main
import "fmt"
func main() {
bodyTypes := [3]string{"Sedan", "SUV", "Convertible"}
fmt.Println(bodyTypes)
fmt.Println(bodyTypes[0])
fmt.Println(bodyTypes[1])
fmt.Println(bodyTypes[2])
} Basic Slice Operations
Demonstrates basic slice operations including append
package main
import "fmt"
func main() {
fuelTypes := []string{"Electric", "Gasoline", "Hybrid"}
fuelTypes = append(fuelTypes, "Diesel", "Hydrogen")
fmt.Println(fuelTypes)
fmt.Println("Length:", len(fuelTypes))
} Slicing a Slice
Creating new slices from existing ones
package main
import "fmt"
func main() {
fuelTypes := []string{"Gasoline", "Diesel", "Electric", "Hybrid", "Hydrogen"}
fmt.Println("Popular:", fuelTypes[0:2])
fmt.Println("Clean:", fuelTypes[2:])
fmt.Println("Electrical:", fuelTypes[2:4])
} Map Basics
Basic operations with maps including declaration and access
package main
import "fmt"
func main() {
carInventory := map[string]int{"Sedan": 25, "SUV": 15, "Convertible": 10}
carInventory["Sedan"] = 20
fmt.Println("Car Inventory:", carInventory)
fmt.Printf("We have %v Sedans\n", carInventory["Sedan"])
} Range with Slices
Using the range keyword with slices
package main
import "fmt"
func main() {
bodyTypes := []string{"Sedan", "SUV", "Convertible"}
for index, bodyType := range bodyTypes {
fmt.Printf("Index %d: %v\n", index, bodyType)
}
} Range with Maps
Iterating over a map using range
package main
import "fmt"
func main() {
carInventory := map[string]int{"Sedan": 25, "SUV": 7, "Convertible": 10}
for bodyType, count := range carInventory {
fmt.Printf("%v -> %v\n", bodyType, count)
}
} + Chapter 4: Functions
Basic Function
Function to add items to inventory
package main
import "fmt"
var carInventory = map[string]int{}
func addToInventory(bodyType string, count int) {
carInventory[bodyType] += count
fmt.Println(bodyType, "added. New Count:", carInventory[bodyType])
}
func main() {
addToInventory("Sedan", 10)
addToInventory("SUV", 7)
addToInventory("Sedan", 2)
fmt.Println("Final Inventory:", carInventory)
} Multiple Return Values
Functions that return multiple values
package main
import "fmt"
func getStatus(available, booked int) (string, string) {
availableStatus := fmt.Sprintf("%v Available", available)
bookedStatus := fmt.Sprintf("%v Booked", booked)
return availableStatus, bookedStatus
}
func main() {
available, booked := getStatus(5, 2)
fmt.Println(available)
fmt.Println(booked)
} Variadic Functions
Function that accepts variable number of arguments
package main
import "fmt"
func sum(numbers ...int) int {
total := 0
for _, n := range numbers {
total += n
}
return total
}
func main() {
fmt.Println("Sum:", sum(1, 2, 3, 4, 5))
fmt.Println("Sum:", sum(700, 800, 900))
odds := []int{1, 3, 5, 7, 9, 11}
fmt.Println("Sum of odds:", sum(odds...))
} Closures
Functions that maintain state between calls
package main
import "fmt"
func sequence() func() int {
i := 0
return func() int {
i++
return i
}
}
func main() {
nextInt := sequence()
fmt.Println(nextInt())
fmt.Println(nextInt())
fmt.Println(nextInt())
newInts := sequence()
fmt.Println("New sequence:", newInts())
} Fibonacci Generator
Closure to generate Fibonacci numbers
package main
import "fmt"
func fib() func() int {
a, b := 0, 1
return func() int {
a, b = b, a+b
return a
}
}
func main() {
f := fib()
for i := 0; i < 10; i++ {
fmt.Print(f(), " ")
}
fmt.Println()
} + Chapter 5: Error handling
Basic Error Handling
Function with error handling for empty input
package main
import (
"errors"
"fmt"
)
var carInventory = map[string]int{}
func getCount(bodyType string) (int, error) {
if bodyType == "" {
return 0, errors.New("bodyType is required")
}
count := carInventory[bodyType]
return count, nil
}
func main() {
count, err := getCount("")
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Count:", count)
} Custom Error Types
Creating and using custom error types
package main
import "fmt"
type ValidationError struct {
Field string
Message string
}
func (e ValidationError) Error() string {
return fmt.Sprintf("%s: %s", e.Field, e.Message)
}
func validateAge(age int) error {
if age < 0 {
return ValidationError{Field: "age", Message: "cannot be negative"}
}
if age > 150 {
return ValidationError{Field: "age", Message: "seems unrealistic"}
}
return nil
}
func main() {
if err := validateAge(-5); err != nil {
fmt.Println("Validation failed:", err)
}
if err := validateAge(25); err == nil {
fmt.Println("Age 25 is valid")
}
} + Chapter 6: Structs
Basic Struct
Defining and using a basic struct
package main
import "fmt"
type BankAccount struct {
AccountNumber string
Balance float64
}
func main() {
account := BankAccount{AccountNumber: "123456789", Balance: 1000.00}
fmt.Println(account)
fmt.Println("Balance:", account.Balance)
account2 := &BankAccount{AccountNumber: "987654321", Balance: 5000.00}
fmt.Println(account2)
} Struct Methods
Adding methods to structs
package main
import "fmt"
type BankAccount struct {
AccountNumber string
Balance float64
}
func (ba BankAccount) DisplayBalance() {
fmt.Printf("Account: %s, Balance: $%.2f\n", ba.AccountNumber, ba.Balance)
}
func (ba *BankAccount) Deposit(amount float64) {
ba.Balance += amount
}
func main() {
account := BankAccount{AccountNumber: "123456789", Balance: 1000.00}
account.DisplayBalance()
account.Deposit(500)
account.DisplayBalance()
} Embedded Structs
Using struct embedding for composition
package main
import (
"fmt"
"time"
)
type AuditInfo struct {
CreatedAt time.Time
LastModified time.Time
}
type BankAccount struct {
AccountNumber string
Balance float64
AuditInfo
}
func main() {
account := BankAccount{
AccountNumber: "123456789",
Balance: 1000.00,
AuditInfo: AuditInfo{CreatedAt: time.Now(), LastModified: time.Now()},
}
fmt.Println("Account:", account.AccountNumber)
fmt.Println("Created:", account.CreatedAt.Format("2006-01-02"))
} + Chapter 7: Interfaces
Basic Interface
Implementing the io.Reader interface
package main
import (
"fmt"
"io"
)
type XMLReader struct {
Data string
}
func (xr *XMLReader) Read(p []byte) (n int, err error) {
copy(p, xr.Data)
return len(xr.Data), io.EOF
}
func ReadConfig(r io.Reader) {
buf := make([]byte, 1024)
n, _ := r.Read(buf)
fmt.Printf("Read %d bytes\n", n)
}
func main() {
xmlReader := &XMLReader{Data: "<?xml version=\"1.0\"?>"}
ReadConfig(xmlReader)
} Empty Interface
Using interface{} to accept any type
package main
import "fmt"
func doSomething(v interface{}) {
fmt.Printf("Value: %v, Type: %T\n", v, v)
}
func main() {
doSomething("Hello")
doSomething(123)
doSomething(4.5)
doSomething(true)
} Type Switch
Handling different types with type switch
package main
import "fmt"
func describe(i interface{}) {
switch v := i.(type) {
case int:
fmt.Printf("Twice %v is %v\n", v, v*2)
case string:
fmt.Printf("%q is %v characters long\n", v, len(v))
case bool:
fmt.Printf("Boolean value: %v\n", v)
default:
fmt.Printf("Unknown type: %T\n", v)
}
}
func main() {
describe(21)
describe("hello")
describe(true)
describe(3.14)
} + Chapter 8: Generics
Generic Print Function
A generic function that works with any type
package main
import "fmt"
func Print[T any](s []T) {
for _, v := range s {
fmt.Println(v)
}
}
func main() {
Print([]string{"Sedan", "SUV", "Convertible"})
fmt.Println("---")
Print([]int{1, 2, 3, 4, 5})
} Generic Pair Struct
A generic struct with type parameters
package main
import "fmt"
type Pair[K, V any] struct {
Key K
Value V
}
func (p Pair[K, V]) Describe() string {
return fmt.Sprintf("Key: %v, Value: %v", p.Key, p.Value)
}
func main() {
intStringPair := Pair[int, string]{Key: 1, Value: "One"}
fmt.Println(intStringPair.Describe())
stringFloatPair := Pair[string, float64]{Key: "Pi", Value: 3.14159}
fmt.Println(stringFloatPair.Describe())
} Generic Constraints
Using type constraints with generics
package main
import (
"fmt"
"golang.org/x/exp/constraints"
)
func Min[T constraints.Ordered](a, b T) T {
if a < b {
return a
}
return b
}
func main() {
fmt.Println(Min(3, 5))
fmt.Println(Min(3.14, 2.71))
fmt.Println(Min("apple", "banana"))
} + Chapter 9: Packages and Modules
This chapter covers organizing Go code with packages and modules.
See the completed code on GitHub: https://github.com/codebuilds-dev/bnk
+ Chapter 10: Project 1 - Stock Analysis CLI
Build a command-line application for stock analysis.
See the completed code on GitHub: https://github.com/codebuilds-dev/opg-analysis
+ Chapter 11: Project 2 - Building A REST API
Build a complete REST API with Go.
See the completed code on GitHub: https://github.com/codebuilds-dev/stock-news