Golang fmt.Appendf function
last modified May 8, 2025
This tutorial explains how to use the fmt.Appendf
function in Go.
We'll cover string formatting basics with practical examples of efficient
string manipulation.
The fmt.Appendf function formats according to a format specifier and appends the result to a byte slice. It's more efficient than fmt.Sprintf when building strings incrementally.
In Go 1.19+, fmt.Appendf
provides a performant way to build
strings by reusing allocated memory. It avoids allocations when appending
to existing slices with sufficient capacity.
Basic fmt.Appendf example
The simplest use of fmt.Appendf
appends formatted text to a
byte slice. This example demonstrates basic string formatting and appending.
package main import ( "fmt" ) func main() { buf := []byte("Existing content: ") name := "Alice" age := 30 buf = fmt.Appendf(buf, "Name: %s, Age: %d", name, age) fmt.Println(string(buf)) }
The code starts with an initial byte slice and appends formatted content. The output combines the original and new content in a single string.
Appending multiple times
fmt.Appendf
can be called multiple times on the same slice.
This example shows incremental string building with multiple appends.
package main import ( "fmt" ) func main() { buf := []byte{} for i := 1; i <= 5; i++ { buf = fmt.Appendf(buf, "Iteration %d, ", i) } fmt.Println("Result:", string(buf)) }
Each loop iteration appends new formatted content to the slice. The final result contains all appended strings in sequence.
Appending different data types
fmt.Appendf
handles various data types through format verbs.
This example demonstrates formatting different types in a single append.
package main import ( "fmt" "time" ) func main() { buf := []byte("Current status: ") now := time.Now() active := true count := 42 buf = fmt.Appendf(buf, "Active: %t, Count: %d, Time: %v", active, count, now) fmt.Println(string(buf)) }
The example shows boolean, integer, and time values formatted together. The format verbs (%t, %d, %v) control how each value is represented.
Preallocating slice capacity
Preallocating slice capacity improves performance with fmt.Appendf
.
This example demonstrates capacity optimization for repeated appends.
package main import ( "fmt" ) func main() { // Preallocate slice with 0 length but 256 capacity buf := make([]byte, 0, 256) for i := 0; i < 10; i++ { buf = fmt.Appendf(buf, "Number %04d\n", i) } fmt.Print(string(buf)) }
The preallocated capacity prevents multiple allocations during appends. This is especially beneficial when the final size is approximately known.
Appending to existing strings
fmt.Appendf
efficiently extends existing strings by converting
them to byte slices. This example shows string extension in practice.
package main import ( "fmt" ) func main() { greeting := "Hello" buf := []byte(greeting) name := "Bob" buf = fmt.Appendf(buf, ", %s! How are you?", name) fmt.Println(string(buf)) }
The example starts with a string, converts it to bytes, then appends more content. This avoids creating intermediate string allocations.
Custom formatting with Appendf
fmt.Appendf
supports all standard format specifiers. This
example demonstrates advanced formatting options.
package main import ( "fmt" "math" ) func main() { buf := []byte("Math results:\n") pi := math.Pi buf = fmt.Appendf(buf, "Pi: %.4f\n", pi) hex := 255 buf = fmt.Appendf(buf, "Hex: %#x\n", hex) sci := 123456789.0 buf = fmt.Appendf(buf, "Scientific: %e\n", sci) fmt.Println(string(buf)) }
The example shows floating-point precision, hexadecimal, and scientific notation formatting. Each append uses a different format specifier.
Performance comparison with Sprintf
This example compares fmt.Appendf
with fmt.Sprintf
to demonstrate performance differences in string building.
package main import ( "fmt" "time" ) func buildWithSprintf(n int) string { var s string for i := 0; i < n; i++ { s += fmt.Sprintf("%d ", i) } return s } func buildWithAppendf(n int) string { buf := make([]byte, 0, n*3) // Estimate 3 bytes per number for i := 0; i < n; i++ { buf = fmt.Appendf(buf, "%d ", i) } return string(buf) } func main() { const count = 10000 start := time.Now() buildWithSprintf(count) sprintfTime := time.Since(start) start = time.Now() buildWithAppendf(count) appendfTime := time.Since(start) fmt.Printf("Sprintf: %v\n", sprintfTime) fmt.Printf("Appendf: %v\n", appendfTime) }
fmt.Appendf
is significantly faster for incremental string
building, especially with preallocated capacity. It avoids intermediate
allocations and copying.
Source
This tutorial covered the fmt.Appendf
function in Go with
practical examples of efficient string formatting and appending.
Author
List all Golang tutorials.