Go Int to String Conversion: 4 Proven Methods Using strconv and fmt
Use strconv.Itoa() for the fastest decimal conversion, or strconv.FormatInt() when you need specific bases like hexadecimal.
Converting integers to strings is a fundamental operation in Go programming. Whether you're formatting log messages or building HTTP responses, the go int to string conversion capabilities in the standard library provide both speed and flexibility. The golang/go repository implements these features primarily in the strconv package, with additional support from fmt.
The strconv Package: Core Go Int to String Conversion Tools
The strconv package in src/strconv/itoa.go provides the canonical implementation for numeric conversions. These functions are optimized for zero-allocation performance in the common decimal case.
strconv.Itoa: The Standard Approach
strconv.Itoa(i int) string is the most common entry point for go int to string conversion. According to the source code in src/strconv/itoa.go (lines 49-52), this function is a thin wrapper that calls FormatInt(int64(i), 10):
package main
import (
"fmt"
"strconv"
)
func main() {
i := -42
s := strconv.Itoa(i) // Returns "-42"
fmt.Printf("Result: %s\n", s)
}
This method handles negative numbers correctly and is the recommended default for decimal string representation.
strconv.FormatInt: Base-Specific Conversion
When you need go int to string conversion in bases other than 10 (such as hexadecimal or binary), use strconv.FormatInt(i int64, base int) string. The base parameter accepts values from 2 to 36.
package main
import (
"fmt"
"strconv"
)
func main() {
i := int64(255)
// Hexadecimal
hex := strconv.FormatInt(i, 16) // "ff"
fmt.Printf("Hex: %s\n", hex)
// Binary
binary := strconv.FormatInt(i, 2) // "11111111"
fmt.Printf("Binary: %s\n", binary)
}
The implementation in src/strconv/itoa.go uses a fast path for base 10 that leverages a pre-computed lookup table (smalls) to avoid expensive division operations.
strconv.AppendInt: Zero-Allocation Building
For high-performance scenarios where you're constructing larger strings or byte buffers, strconv.AppendInt(dst []byte, i int64, base int) []byte appends the conversion directly to an existing slice without allocating a new string.
package main
import (
"fmt"
"strconv"
)
func main() {
i := int64(-42)
// Build string efficiently
buf := []byte("Error code: ")
buf = strconv.AppendInt(buf, i, 10)
fmt.Println(string(buf)) // "Error code: -42"
}
This function is defined in src/strconv/itoa.go and shares the same optimized conversion logic as FormatInt, making it ideal for log formatting and network protocol implementations.
Alternative: fmt.Sprintf for Go Int to String Conversion
While strconv provides the fastest go int to string conversion, the fmt package offers flexibility when you need formatted output with padding, alignment, or when you're already using fmt for other operations.
package main
import "fmt"
func main() {
i := 42
// Basic decimal
s := fmt.Sprintf("%d", i)
// Zero-padded to 5 digits
padded := fmt.Sprintf("%05d", i) // "00042"
fmt.Printf("Standard: %s, Padded: %s\n", s, padded)
}
Note that fmt.Sprintf incurs higher overhead due to reflection and parsing of format strings. For hot paths and high-throughput applications, prefer the strconv methods.
How Go Int to String Conversion Works Under the Hood
The golang/go repository implements these conversions with performance as a primary concern. In src/strconv/itoa.go, the FormatInt function handles the common decimal case (base 10) using a lookup table strategy:
- Small number optimization: Numbers 0-99 are mapped directly via the
smallsstring table defined insrc/internal/strconv/itoa.go, eliminating division operations for common values. - Digit extraction: For larger numbers, the algorithm processes two digits at a time using the
smallstable, reducing the number of expensive division operations by half compared to naive implementations. - Allocation-free path: The decimal conversion writes into a fixed-size array on the stack, then creates a string header pointing to this data, avoiding heap allocations in the common case.
For non-decimal bases, formatBits in src/strconv/itoa.go uses either bit-shifting (for bases that are powers of two) or division/remainder loops, depending on the base parameter.
Summary
- Use
strconv.Itoa()for the fastest, simplest go int to string conversion in base 10. - Use
strconv.FormatInt()when converting to hexadecimal, binary, or other bases (2-36). - Use
strconv.AppendInt()for zero-allocation appending to byte slices in performance-critical code. - Use
fmt.Sprintf()only when you need complex formatting and performance is not the primary concern. - The implementation in
src/strconv/itoa.gouses lookup tables and stack allocation to minimize overhead.
Frequently Asked Questions
What is the fastest way to convert int to string in Go?
strconv.Itoa() is the fastest method for decimal go int to string conversion. It uses optimized lookup tables and avoids heap allocations by writing to stack-allocated buffers before creating the final string. According to the source in src/strconv/itoa.go, it processes two digits at a time using pre-computed string tables to minimize expensive division operations.
Does strconv.Itoa handle negative numbers?
Yes, strconv.Itoa() correctly handles negative integers. The function converts the int to int64 and passes it to FormatInt, which detects negative values, records the sign, and processes the absolute value before prepending the minus sign to the result buffer. This ensures that values like -42 convert to "-42" correctly.
When should I use fmt.Sprintf instead of strconv?
Use fmt.Sprintf when you need formatting features beyond simple conversion, such as zero-padding (%05d), hexadecimal with 0x prefixes (%#x), or alignment. However, for hot paths and high-throughput applications, avoid fmt.Sprintf for go int to string conversion because it incurs reflection overhead and format string parsing costs that strconv methods avoid.
Is Go int to string conversion allocation-free?
For the common decimal case using strconv.Itoa() or strconv.FormatInt() with base 10, the conversion is allocation-free. The implementation in src/strconv/itoa.go writes digits into a fixed-size array on the stack, then creates a string header pointing to this stack data. However, when using fmt.Sprintf or when the compiler cannot prove the string doesn't escape, allocations may occur.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →