Skip to content

fmt, strings, and strconv

The fmt package is the entry point for almost all output in Go. Three functions cover the vast majority of use cases:

  • fmt.Println(args...) — prints each argument separated by spaces, followed by a newline.
  • fmt.Printf(format, args...) — prints using a format string with verbs.
  • fmt.Sprintf(format, args...) — returns the formatted string instead of printing it.
VerbMeaning
%vDefault representation
%+vStruct with field names
%#vGo-syntax representation
%TType of the value
%dDecimal integer
%sString (unquoted)
%qDouble-quoted string with Go escaping
%fFloating-point decimal
type Person struct { Name string; Age int }
p := Person{"Alice", 30}
fmt.Printf("%v\n", p) // {Alice 30}
fmt.Printf("%+v\n", p) // {Name:Alice Age:30}
fmt.Printf("%#v\n", p) // main.Person{Name:"Alice", Age:30}
fmt.Printf("%T\n", p) // main.Person

The strings package provides functions for searching, splitting, joining, and transforming strings. Strings in Go are immutable UTF-8 byte sequences; these functions return new strings rather than modifying in place.

s := "hello, world"
strings.Contains(s, "world") // true
strings.HasPrefix(s, "hello") // true
strings.Split(s, ", ") // ["hello" "world"]
strings.Join([]string{"a","b"}, "-") // "a-b"
strings.ReplaceAll(s, "l", "L") // "heLLo, worLd"
strings.ToUpper(s) // "HELLO, WORLD"
strings.TrimSpace(" hi ") // "hi"

strings.Builder — efficient concatenation

Section titled “strings.Builder — efficient concatenation”

When building a string from many pieces in a loop, use strings.Builder instead of +=. The += operator allocates a new string on every iteration; Builder writes into a growing buffer and only allocates the final string once.

var b strings.Builder
for i := 0; i < 5; i++ {
fmt.Fprintf(&b, "item%d ", i)
}
result := strings.TrimSpace(b.String()) // "item0 item1 item2 item3 item4"

strconv converts between strings and numeric types. The most common functions:

n, err := strconv.Atoi("42") // string → int
s := strconv.Itoa(42) // int → string
f, err := strconv.ParseFloat("3.14", 64) // string → float64
b, err := strconv.ParseBool("true") // string → bool

Atoi and ParseFloat return (value, error) because the input might not be a valid number. Always check the error before using the value.

package main
import (
"fmt"
"strconv"
"strings"
)
type Person struct {
Name string
Age int
}
func main() {
// fmt verbs
p := Person{Name: "Alice", Age: 30}
fmt.Printf("%v\n", p)
fmt.Printf("%+v\n", p)
fmt.Printf("%#v\n", p)
fmt.Printf("%T\n", p)
fmt.Printf("%d %s %q\n", 42, "hello", "world")
// Sprintf builds a string
s := fmt.Sprintf("Name: %s, Age: %d", p.Name, p.Age)
fmt.Println(s)
// strings package
text := " Go is great "
fmt.Println(strings.TrimSpace(text))
fmt.Println(strings.Contains(text, "great"))
fmt.Println(strings.ToUpper(strings.TrimSpace(text)))
words := strings.Split("one,two,three", ",")
fmt.Println(words)
fmt.Println(strings.Join(words, " | "))
fmt.Println(strings.ReplaceAll("aabbcc", "b", "x"))
// strings.Builder — efficient concatenation
var b strings.Builder
for i := 0; i < 3; i++ {
fmt.Fprintf(&b, "item%d ", i)
}
fmt.Println(strings.TrimSpace(b.String()))
// strconv
n, err := strconv.Atoi("123")
if err == nil {
fmt.Println(n + 1)
}
fmt.Println(strconv.Itoa(456))
f, err := strconv.ParseFloat("3.14", 64)
if err == nil {
fmt.Printf("%.2f\n", f)
}
}
Which format verb prints a struct with its field names?
What does strings.ReplaceAll("aabbcc", "b", "x") return?
Why is strings.Builder preferred over += for building strings in a loop?
strconv.Atoi("42") returns which types?