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 checkstrings.HasPrefix/HasSuffix(s, prefix)strings.Split(s, sep)— splits into a slicestrings.Join(parts, sep)— joins a slice into a stringstrings.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 placesort.Slice(s, less)— sort any slice with a custom comparatorsort.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 durationt.Sub(other)— duration between two timest.Format(layout)— format using Go's reference time"2006-01-02 15:04:05"time.Parse(layout, value)— parse a string intotime.Timetime.Since(t)— shorthand fortime.Now().Sub(t)- Duration constants:
time.Second,time.Minute,time.Hour
encoding/json Package
json.Marshal(v)— Go value → JSON bytesjson.Unmarshal(data, &v)— JSON bytes → Go valuejson.NewEncoder(w).Encode(v)— stream toio.Writerjson.NewDecoder(r).Decode(&v)— stream fromio.Reader- Struct tags control field names:
json:"name,omitempty"
math Package
math.Abs, math.Sqrt, math.Pow, math.Log, math.Floor, math.Ceilmath.Max, math.Min- Constants:
math.Pi,math.E,math.MaxFloat64,math.MaxInt
fmt Package Highlights
%v— default format;%+vincludes field names for structs;%#vGo syntax%T— type of the value%d, %f, %s, %q, %x— integer, float, string, quoted string, hexfmt.Sprintf— format to string;fmt.Fprintf— format toio.Writerfmt.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
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.
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.
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?