Golang fmt.Append function
last modified May 8, 2025
This tutorial explains how to use the fmt.Append
function in Go.
We'll cover string building basics with practical examples of efficient string
manipulation.
The fmt.Append function is used to efficiently build strings by appending formatted data to byte slices. It provides a performance advantage over string concatenation for complex string building operations.
In Go, fmt.Append
is part of the fmt package and was introduced
in Go 1.19. It works similarly to fmt.Printf
but writes to a
byte slice instead of an io.Writer.
Basic fmt.Append example
The simplest use of fmt.Append
appends formatted strings to a
byte slice. This example demonstrates basic string appending.
Note: The function returns a new slice, it doesn't modify
the original.
package main import ( "fmt" ) func main() { buf := []byte("Hello, ") buf = fmt.Append(buf, "World!") fmt.Println(string(buf)) // Convert back to string for printing // Append multiple values nums := []byte("Numbers: ") nums = fmt.Append(nums, 1, 2, 3) fmt.Println(string(nums)) }
The function appends formatted values to the byte slice. The original slice may be empty or contain existing data.
Appending with formatting verbs
fmt.Append
supports the same formatting verbs as fmt.Printf
.
This example shows formatted number appending.
package main import ( "fmt" ) func main() { buf := []byte("Formatted values: ") // Append with different format verbs buf = fmt.Appendf(buf, "Int: %d, Float: %.2f, Bool: %t", 42, 3.14159, true) fmt.Println(string(buf)) // Hexadecimal example hexBuf := []byte("Hex: ") hexBuf = fmt.Appendf(hexBuf, "%x", 255) fmt.Println(string(hexBuf)) }
The Appendf
variant allows precise control over formatting.
Format verbs work exactly like in other fmt package functions.
Appending slices and arrays
fmt.Append
can append entire slices and arrays. This example
shows how to efficiently build strings from collections.
package main import ( "fmt" ) func main() { names := []string{"Alice", "Bob", "Charlie"} buf := []byte("Names: ") // Append each name with separator for _, name := range names { buf = fmt.Append(buf, name, ", ") } // Remove trailing comma and space if len(names) > 0 { buf = buf[:len(buf)-2] } fmt.Println(string(buf)) // Alternative with fmt.Appendln buf = []byte("Names:\n") for _, name := range names { buf = fmt.Appendln(buf, name) } fmt.Println(string(buf)) }
The example shows two approaches: comma-separated values and line-separated. The function handles each element's string conversion automatically.
Performance comparison with strings.Builder
fmt.Append
can be more efficient than strings.Builder for some
use cases. This example compares the performance characteristics.
package main import ( "fmt" "strings" "time" ) func buildWithBuilder(count int) string { var b strings.Builder for i := 0; i < count; i++ { fmt.Fprintf(&b, "Item %d, ", i) } return b.String() } func buildWithAppend(count int) string { buf := []byte{} for i := 0; i < count; i++ { buf = fmt.Append(buf, "Item ", i, ", ") } return string(buf) } func main() { const count = 10000 start := time.Now() buildWithBuilder(count) builderTime := time.Since(start) start = time.Now() buildWithAppend(count) appendTime := time.Since(start) fmt.Printf("strings.Builder: %v\n", builderTime) fmt.Printf("fmt.Append: %v\n", appendTime) }
The performance difference depends on the use case. fmt.Append
often wins for many small appends, while strings.Builder may be better for
fewer, larger writes.
Appending custom types
fmt.Append
works with any type that implements the Stringer
interface. This example demonstrates custom type appending.
package main import ( "fmt" ) type Point struct { X, Y int } func (p Point) String() string { return fmt.Sprintf("(%d,%d)", p.X, p.Y) } func main() { buf := []byte("Points: ") p1 := Point{10, 20} p2 := Point{30, 40} buf = fmt.Append(buf, p1, " ", p2) fmt.Println(string(buf)) // Works with pointers too buf = []byte("Pointer points: ") buf = fmt.Append(buf, &p1, " ", &p2) fmt.Println(string(buf)) }
The String method is automatically called when appending custom types. This provides flexible formatting for user-defined data structures.
Error handling with fmt.Append
fmt.Append
doesn't return errors, making it simpler than some
other formatting functions. This example shows error-free usage patterns.
package main import ( "fmt" ) func main() { // No error handling needed buf := []byte{} buf = fmt.Append(buf, "This", " ", "works", " ", 123) fmt.Println(string(buf)) // Even with invalid format strings, it won't panic buf = []byte{} buf = fmt.Appendf(buf, "Value: %d", "not a number") // %d expects number fmt.Println(string(buf)) // Still produces output (with wrong format) // For critical formatting, validate first value := "not a number" if _, err := fmt.Sscanf(value, "%d", new(int)); err == nil { buf = fmt.Appendf(buf, "Valid number: %d", value) } else { buf = fmt.Append(buf, "Invalid number: ", value) } fmt.Println(string(buf)) }
While fmt.Append
won't panic on format mismatches, the output
may not be as expected. For critical formatting, validate inputs first.
Building complex strings
fmt.Append
excels at building complex strings incrementally.
This example shows a multi-step string construction.
package main import ( "fmt" "time" ) func buildReport() []byte { buf := []byte("REPORT\n") buf = fmt.Appendf(buf, "Generated: %s\n\n", time.Now().Format(time.RFC1123)) // Add header buf = fmt.Append(buf, "ITEM".padRight(20), "QUANTITY".padRight(10), "PRICE\n") buf = fmt.Append(buf, "----".padRight(20), "--------".padRight(10), "-----\n") // Add items items := []struct { name string quantity int price float64 }{ {"Widget", 5, 12.99}, {"Gadget", 2, 29.95}, {"Thingy", 10, 1.49}, } for _, item := range items { buf = fmt.Appendf(buf, "%-20s%-10d$%.2f\n", item.name, item.quantity, item.price) } // Add footer buf = fmt.Append(buf, "\nTotal items: ", len(items), "\n") return buf } func main() { report := buildReport() fmt.Println(string(report)) } // Helper function for padding func (s string) padRight(width int) string { if len(s) >= width { return s } return s + strings.Repeat(" ", width-len(s)) }
The example demonstrates building a formatted report with headers, data rows,
and footer. fmt.Append
efficiently handles each part.
Source
This tutorial covered the fmt.Append
function in Go with practical
examples of efficient string building and formatting.
Author
List all Golang tutorials.