GO

Go Fundamentals

18 lessons

Progress0%
1. Introduction to Go
1What is Go?
2. Variables and Data Types
1Data Types in Go
3. Control Flow
If, For, and SwitchDefer, Panic, Recover
4. Functions
Function BasicsError Handling
5. Structs and Methods
StructsMethods and Interfaces
6. Concurrency
Goroutines and ChannelsSelect and Sync
7. Maps & Slices Advanced
Slices Deep DiveMaps Operations & Patterns
8. Interfaces Deep Dive
Interface Composition & anyCommon Interfaces & Patterns
9. Packages & Modules
Package SystemGo Modules & Workspace
10. Testing & Standard Library
Testing in GoStandard Library Essentials
All Tutorials
GoTesting & Standard Library
Lesson 18 of 18 min
Chapter 10 · Lesson 2

Standard Library Essentials

Standard Library Essentials

Go's standard library is comprehensive, well-documented, and designed to work together. Mastering a handful of key packages covers the majority of everyday tasks.

strings Package Provides functions for UTF-8 string manipulation:

  • strings.Contains(s, substr) — substring check
  • strings.HasPrefix/HasSuffix(s, prefix)
  • strings.Split(s, sep) — splits into a slice
  • strings.Join(parts, sep) — joins a slice into a string
  • strings.TrimSpace(s) / strings.Trim(s, cutset)
  • strings.ToLower/ToUpper(s)
  • strings.ReplaceAll(s, old, new)
  • strings.Builder — efficient incremental string construction

strconv Package Converts between strings and primitive types:

  • strconv.Atoi("42") → (42, nil)
  • strconv.Itoa(42) → "42"
  • strconv.ParseFloat("3.14", 64)
  • strconv.FormatInt(255, 16) → "ff" (base 16)
  • strconv.ParseBool("true")

sort Package

  • sort.Ints(s), sort.Strings(s), sort.Float64s(s) — sort slices in place
  • sort.Slice(s, less) — sort any slice with a custom comparator
  • sort.Search(n, f) — binary search on a sorted collection

time Package

  • time.Now() — current local time (time.Time)
  • t.Add(d time.Duration) — add a duration
  • t.Sub(other) — duration between two times
  • t.Format(layout) — format using Go's reference time "2006-01-02 15:04:05"
  • time.Parse(layout, value) — parse a string into time.Time
  • time.Since(t) — shorthand for time.Now().Sub(t)
  • Duration constants: time.Second, time.Minute, time.Hour

encoding/json Package

  • json.Marshal(v) — Go value → JSON bytes
  • json.Unmarshal(data, &v) — JSON bytes → Go value
  • json.NewEncoder(w).Encode(v) — stream to io.Writer
  • json.NewDecoder(r).Decode(&v) — stream from io.Reader
  • Struct tags control field names: json:"name,omitempty"

math Package

  • math.Abs, math.Sqrt, math.Pow, math.Log, math.Floor, math.Ceil
  • math.Max, math.Min
  • Constants: math.Pi, math.E, math.MaxFloat64, math.MaxInt

fmt Package Highlights

  • %v — default format; %+v includes field names for structs; %#v Go syntax
  • %T — type of the value
  • %d, %f, %s, %q, %x — integer, float, string, quoted string, hex
  • fmt.Sprintf — format to string; fmt.Fprintf — format to io.Writer
  • fmt.Sscanf — parse from string

The standard library's packages are tightly integrated: json.NewDecoder accepts an io.Reader, so you can decode directly from HTTP response bodies, files, or any other reader without buffering the entire content in memory first.

Code Examples

strings and strconv manipulation pipelinego
package main

import (
    "fmt"
    "strconv"
    "strings"
)

func parseCSVLine(line string) []string {
    fields := strings.Split(line, ",")
    for i, f := range fields {
        fields[i] = strings.TrimSpace(f)
    }
    return fields
}

func main() {
    // strings package
    s := "  Hello, Go World!  "
    fmt.Println(strings.TrimSpace(s))
    fmt.Println(strings.ToUpper(s))
    fmt.Println(strings.Contains(s, "Go"))
    fmt.Println(strings.ReplaceAll(s, "Go", "Gopher"))
    fmt.Println(strings.HasPrefix(strings.TrimSpace(s), "Hello"))
    parts := strings.Split("a,b,c,d", ",")
    fmt.Println(parts)
    fmt.Println(strings.Join(parts, " | "))

    // strings.Builder — efficient concatenation
    var b strings.Builder
    for i := 0; i < 5; i++ {
        fmt.Fprintf(&b, "item%d ", i)
    }
    fmt.Println(strings.TrimSpace(b.String()))

    // strconv
    n, err := strconv.Atoi("42")
    fmt.Println(n, err)
    fmt.Println(strconv.Itoa(255))
    fmt.Println(strconv.FormatInt(255, 16))  // hex
    fmt.Println(strconv.FormatInt(255, 2))   // binary
    f, _ := strconv.ParseFloat("3.14159", 64)
    fmt.Printf("%.3f\n", f)

    // CSV parsing pipeline
    line := " Alice , 30 , engineer "
    row := parseCSVLine(line)
    fmt.Println(row)
}

strings.Builder avoids the quadratic cost of repeated += concatenation. strconv converts between string and numeric types with explicit error handling. fmt.Fprintf works with any io.Writer, including strings.Builder.

JSON encoding and decodinggo
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "log"
)

type Address struct {
    Street string `json:"street"`
    City   string `json:"city"`
    Zip    string `json:"zip,omitempty"` // omit if empty
}

type Person struct {
    Name    string  `json:"name"`
    Age     int     `json:"age"`
    Email   string  `json:"email,omitempty"`
    Address Address `json:"address"`
    Tags    []string `json:"tags,omitempty"`
}

func main() {
    // Marshal (Go -> JSON)
    p := Person{
        Name: "Alice",
        Age:  30,
        Address: Address{Street: "123 Main St", City: "Springfield"},
        Tags: []string{"admin", "user"},
    }

    data, err := json.Marshal(p)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(string(data))

    // MarshalIndent for pretty output
    pretty, _ := json.MarshalIndent(p, "", "  ")
    fmt.Println(string(pretty))

    // Unmarshal (JSON -> Go)
    jsonStr := `{"name":"Bob","age":25,"address":{"street":"456 Elm St","city":"Shelbyville","zip":"12345"}}`
    var p2 Person
    if err := json.Unmarshal([]byte(jsonStr), &p2); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Decoded: %+v\n", p2)

    // Streaming decode with NewDecoder
    stream := bytes.NewBufferString(`{"name":"Carol","age":28,"address":{"street":"789 Oak Ave","city":"Capital City"}}`)
    var p3 Person
    if err := json.NewDecoder(stream).Decode(&p3); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Streamed: %s, age %d\n", p3.Name, p3.Age)
}

Struct tags (json:"name") map Go field names to JSON keys. omitempty skips zero-value fields. NewDecoder streams from any io.Reader — memory-efficient for large payloads like HTTP responses.

time operations and formattinggo
package main

import (
    "fmt"
    "sort"
    "time"
)

func main() {
    // Current time
    now := time.Now()
    fmt.Println("Now:", now.Format("2006-01-02 15:04:05"))

    // Go's reference time: Mon Jan 2 15:04:05 MST 2006
    // Use these exact values in format strings — they are mnemonics
    fmt.Println("Date:", now.Format("2006-01-02"))
    fmt.Println("Time:", now.Format("15:04:05"))
    fmt.Println("RFC3339:", now.Format(time.RFC3339))

    // Arithmetic
    in2Hours := now.Add(2 * time.Hour)
    yesterday := now.Add(-24 * time.Hour)
    fmt.Println("In 2h:", in2Hours.Format("15:04:05"))
    fmt.Printf("Since yesterday: %.1f hours\n", time.Since(yesterday).Hours())

    // Parsing
    layout := "2006-01-02"
    t, err := time.Parse(layout, "2024-06-15")
    if err != nil {
        fmt.Println("parse error:", err)
    } else {
        fmt.Println("Parsed:", t.Format("January 2, 2006"))
        fmt.Println("Weekday:", t.Weekday())
    }

    // Sorting times
    events := []time.Time{
        now.Add(3 * time.Hour),
        now.Add(-1 * time.Hour),
        now.Add(1 * time.Hour),
    }
    sort.Slice(events, func(i, j int) bool {
        return events[i].Before(events[j])
    })
    fmt.Println("\nSorted events:")
    for _, e := range events {
        diff := e.Sub(now)
        fmt.Printf("  %+.0fh from now\n", diff.Hours())
    }
}

Go's time format uses the reference time 2006-01-02 15:04:05 as a mnemonic (1-2-3-4-5-6 in time order). time.Duration arithmetic is type-safe. sort.Slice with Before() sorts time.Time values correctly.

Quick Quiz

1. What is the correct Go reference time string for formatting dates as `YYYY-MM-DD`?

2. What is the advantage of `json.NewDecoder(r).Decode(&v)` over `json.Unmarshal(data, &v)`?

3. What does the `omitempty` option in a JSON struct tag do?

4. Which strconv function converts a string to an integer and why is it preferred over fmt.Sscanf for this purpose?

Was this lesson helpful?

PreviousFinish