The strconv package converts between strings and the basic Go types — int, float64, bool. Anything that comes in as text (from a user, a file, a network request) and needs to become a number, or vice versa, goes through strconv.
Import it:
import "strconv"
At a glance
| Direction | Simple | Powerful |
|---|---|---|
| string → int | Atoi | ParseInt |
| int → string | Itoa | FormatInt |
| string → float | — | ParseFloat |
| float → string | — | FormatFloat |
| string → bool | — | ParseBool |
| bool → string | — | FormatBool |
| Add escapes/quotes | — | Quote, Unquote |
Use the simple version when you have a base-10 integer string. Use the powerful version when you need to control base (binary, hex), bit size, or precision.
The rest of this page walks through each pair with examples.
Integers
Atoi and Itoa — the everyday pair
The names come from C: ASCII to integer and the reverse.
n, err := strconv.Atoi("42") // n = 42, err = nil
if err != nil {
// handle bad input
}
s := strconv.Itoa(42) // s = "42"
Atoi only handles base-10 integers that fit in an int. For anything fancier, use ParseInt.
ParseInt — base and bit size
strconv.ParseInt(s, base, bitSize)
base:0(auto-detect from0x/0o/0bprefix), or2–36bitSize:0(int),8,16,32,64. Limits the value range.
strconv.ParseInt("42", 10, 64) // 42, nil
strconv.ParseInt("ff", 16, 64) // 255, nil
strconv.ParseInt("1010", 2, 64) // 10, nil
strconv.ParseInt("0xff", 0, 64) // 255, nil (auto-detect from prefix)
strconv.ParseInt("300", 10, 8) // 0, error (300 > int8 max of 127)
The return type is always int64 regardless of bitSize — you cast it down yourself:
n64, _ := strconv.ParseInt("100", 10, 32)
n := int32(n64)
FormatInt — int to string in any base
strconv.FormatInt(42, 10) // "42"
strconv.FormatInt(255, 16) // "ff"
strconv.FormatInt(10, 2) // "1010"
strconv.FormatInt(-42, 10) // "-42"
FormatInt takes an int64, so cast up if you have a smaller int:
n := int32(42)
s := strconv.FormatInt(int64(n), 10) // "42"
Itoa(n)is justFormatInt(int64(n), 10). UseItoawhen you have anintand want base 10. UseFormatIntfor everything else.
Unsigned variants — ParseUint and FormatUint
Same shape as ParseInt/FormatInt, but for uint64. Use these when negative values would be a bug (port numbers, sizes, IDs).
strconv.ParseUint("8080", 10, 16) // 8080, nil
strconv.FormatUint(8080, 10) // "8080"
Floats
ParseFloat
strconv.ParseFloat("3.14", 64) // 3.14, nil
strconv.ParseFloat("1e6", 64) // 1000000, nil
strconv.ParseFloat("not a number", 64) // 0, error
The second arg is the bit size: 32 or 64. Use 64 unless you have a reason not to.
FormatFloat
strconv.FormatFloat(f, format, precision, bitSize)
The format byte chooses the output style:
| Format | What it does | Example for 3.14159 |
|---|---|---|
'f' | Plain decimal | "3.14159" |
'e' | Scientific (lowercase e) | "3.14159e+00" |
'E' | Scientific (uppercase E) | "3.14159E+00" |
'g' | %e for large/small, %f otherwise | "3.14159" |
'b' | Binary exponent form (rare) | — |
strconv.FormatFloat(3.14159, 'f', 2, 64) // "3.14"
strconv.FormatFloat(3.14159, 'f', -1, 64) // "3.14159" (-1 = shortest accurate)
strconv.FormatFloat(1234.5, 'e', 3, 64) // "1.234e+03"
For most uses,
fmt.Sprintf("%.2f", x)is cleaner thanFormatFloat. Reach forFormatFloatwhen you need the exact shortest representation (precision = -1).
Booleans
strconv.ParseBool("true") // true, nil
strconv.ParseBool("1") // true, nil
strconv.ParseBool("yes") // false, error (only 1/t/T/TRUE/true/True and 0/f/F/FALSE/false/False)
strconv.FormatBool(true) // "true"
ParseBool accepts a fixed set of strings. For anything else (like "yes"/"no"), match it yourself.
Quoting strings
Quote and Unquote handle Go-style string literals — adding escape sequences, surrounding quotes, etc. Useful when generating Go code, logging values safely, or parsing config files that use Go-quoted strings.
strconv.Quote("Hello\nWorld") // `"Hello\nWorld"` (with literal \n)
strconv.Quote(`raw "quoted" text`) // `"raw \"quoted\" text"`
s, err := strconv.Unquote(`"Hello\nWorld"`)
// s = "Hello\nWorld" (the actual newline character)
Variants:
QuoteRune('A')→"'A'"QuoteToASCII("héllo")→"\"h\\u00e9llo\""(escapes non-ASCII)Unquoteworks on"...",'...', and`...`.
Handling errors — NumError
Every Parse* function returns an error that’s actually a *strconv.NumError. You can extract it with errors.As to see exactly what went wrong:
n, err := strconv.Atoi("abc")
if err != nil {
var numErr *strconv.NumError
if errors.As(err, &numErr) {
fmt.Println("Function:", numErr.Func) // "Atoi"
fmt.Println("Input:", numErr.Num) // "abc"
fmt.Println("Inner:", numErr.Err) // strconv.ErrSyntax
}
}
Two sentinel errors you can check against:
strconv.ErrSyntax— the string wasn’t a valid numberstrconv.ErrRange— the number was valid but didn’t fit in the bit size
_, err := strconv.ParseInt("999999999999999999999", 10, 32)
errors.Is(err, strconv.ErrRange) // true
Common interview patterns
Read an int from stdin
var s string
fmt.Scan(&s)
n, err := strconv.Atoi(s)
if err != nil {
fmt.Println("not a valid number")
return
}
fmt.Println("doubled:", n*2)
Parse a hex color string
hex := "ff8800"
n, _ := strconv.ParseUint(hex, 16, 32)
r := (n >> 16) & 0xff // 255
g := (n >> 8) & 0xff // 136
b := n & 0xff // 0
Convert a slice of ints to a comma-separated string
nums := []int{1, 2, 3, 4}
parts := make([]string, len(nums))
for i, n := range nums {
parts[i] = strconv.Itoa(n)
}
result := strings.Join(parts, ",") // "1,2,3,4"
Sum the digits of a number-string
func digitSum(s string) (int, error) {
sum := 0
for _, c := range s {
d, err := strconv.Atoi(string(c))
if err != nil {
return 0, err
}
sum += d
}
return sum, nil
}
Quick rules of thumb
- Base-10 int from a string? →
Atoi - Int to base-10 string? →
Itoa - Any other base, or need bit-size control? →
ParseInt/FormatInt - Floats? →
ParseFloat(s, 64); for printing usefmt.Sprintf("%.2f", x) - Bool from text? →
ParseBool(handlestrue/false/1/0/t/fetc.) - Need to know why parsing failed? →
errors.Is(err, strconv.ErrSyntax)orErrRange
Common mistakes
- Ignoring the error from
Atoi—n, _ := strconv.Atoi(s)silently gives0on bad input, which is a bug waiting to happen. - Using
Atoifor hex —Atoi("ff")fails. UseParseInt("ff", 16, 64). - Forgetting to cast
ParseInt’sint64result —var n int = strconv.ParseInt(...)won’t compile. fmt.Sprintf("%d", n)vsstrconv.Itoa(n)— both work;Itoais faster and clearer when you only need the number.ParseBool("yes")— fails. The valid strings are1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False.