Saturday, February 7, 2026
String Formatting
Akash AmanUpdated: February 2026
String Formatting
Concept: String formatting in Go is primarily handled by the fmt package. It uses "verbs" (placeholders starting with %) to tell Go how to transform a variable into a string representation.
Why: Go is strictly typed, so you cannot simply concatenate a string and an integer (e.g., "Age: " + 10). Formatting allows for type-safe, readable, and highly controlled string construction.
The Core Functions
| Function | Output Destination | Behavior |
|---|---|---|
fmt.Printf | Standard Output | Prints formatted string to the console. |
fmt.Sprintf | Returns a String | Saves the formatted result to a variable. |
fmt.Fprintf | io.Writer | Sends formatted text to a file, network socket, or buffer. |
The General Purpose Verbs
Concept: These are the "Swiss Army Knives" of formatting. If you aren't sure of the specific type, or want a quick look at the data, use these.
%v(Value): The default format. It prints the value in a "natural" way.%+v(Struct+): When printing structs, this adds the field names.%#v(Go-syntax): Prints the value as it would appear in Go source code.%T(Type): Prints the data type of the variable.
How %v Really Works
- For Basic Types: If you have a pointer to a basic type like an
intor astring,%vwill indeed print the hexadecimal memory address. - For Structs: If you have a pointer to a
struct,%vis smart. By default, it will dereference the pointer and print the struct's contents formatted inside braces. - For Types with a
String()method: If the type (or its pointer) has a custom stringer method,%vwill call that method instead of printing the address.
Comparison Table
| Data Type | Code Example | Output with %v |
|---|---|---|
| Pointer to Int | p := new(int) | 0xc0000120b0 (Address) |
| Pointer to Struct | p := &User{ID: 1} | &{1} (Values) |
| Pointer to Stringer | p := time.Now() | 2026-02-07 ... (Formatted String) |
Behavioral Reason: Debugging Visibility
- In languages like JavaScript,
console.log(object)gives you a deep view. In Go, a simple%von a pointer only gives you the memory address. Using%+vor%#vis the "Go way" to inspect the internal state of objects during development without writing custom "Stringer" methods.
Type-Specific Verbs
Concept: To ensure precise control over memory representation (crucial for your IoT and low-level interests), Go provides explicit verbs for different data types.
Integers & Numbers
%d: Base 10 (Standard integer).%b: Binary (Great for checking bitmasks or IoT sensor data).%x/%X**: Hexadecimal (Used for memory addresses or color codes).%f: Floating point.
Strings & Characters
%s: Basic string output.%q: Quoted string. Safely escapes special characters.%c: Character (converts an integer/rune to its Unicode symbol).
Width and Precision
Concept: You can control how much space a value takes up and how many decimal places are shown.
- Width:
%5dpads the integer to at least 5 characters wide. - Precision:
%.2flimits a float to 2 decimal places.
The "Right-Align" Logic
- By default, width-padding happens on the left (right-aligning the text). To left-align (pad on the right), use a minus sign:
%-5d.
Formatting Performance
Crucial: The Reflection Cost
Behavior: Functions like Printf and Sprintf use Reflection (reflect package) internally to figure out the type of variable you passed at runtime.
Why this matters:
- Performance: In a high-frequency loop (like processing millions of IoT sensor packets),
fmt.Sprintfis significantly slower than direct string conversion. - Alternative: For maximum performance, use the
strconvpackage (e.g.,strconv.Itoa(i)) which avoids reflection.
Crux
%vis for quick development;%d/%s/%fis for intentional formatting.%#vis your best friend for debugging complex structs.%qis essential when logging strings that might contain hidden newlines or tabs.- Memory/Speed: Use
fmtfor readability and UI; usestrconvfor high-performance data processing.