Go by Example

Number Parsing

strconv.Atoi and ParseInt for integers, ParseFloat for floats, FormatInt and Itoa for the reverse, and error handling on invalid input.

The strconv package converts between strings and numeric types. Atoi is a shorthand for converting a decimal string to int; the Parse* functions give full control over base and bit size.

strconv.Atoi converts a decimal string to int. It returns both the value and an error. Always check the error - a failed parse returns 0, which is also a valid integer.

package main
 
import (
    "fmt"
    "strconv"
)
 
func main() {
    n, err := strconv.Atoi("42")
    if err != nil {
        panic(err)
    }
    fmt.Println(n) // 42
 
    _, err = strconv.Atoi("abc")
    fmt.Println(err) // strconv.Atoi: parsing "abc": invalid syntax
}

strconv.ParseInt parses a string in any base (2–36) and returns an int64. The bitSize argument (8, 16, 32, 64) specifies the integer type the result must fit into - it does not limit the input string, only the return type's range.

package main
 
import (
    "fmt"
    "strconv"
)
 
func main() {
    // base 10, fits in int64
    i64, _ := strconv.ParseInt("255", 10, 64)
    fmt.Println(i64) // 255
 
    // base 2 (binary)
    bin, _ := strconv.ParseInt("11111111", 2, 64)
    fmt.Println(bin) // 255
 
    // base 16 (hex), constrained to int8 range
    _, err := strconv.ParseInt("200", 16, 8) // 0x200 = 512, overflows int8
    fmt.Println(err)
}

strconv.ParseFloat converts a string to float64 or float32. strconv.FormatInt and strconv.Itoa go the other direction - number to string.

package main
 
import (
    "fmt"
    "strconv"
)
 
func main() {
    f, _ := strconv.ParseFloat("3.14159", 64)
    fmt.Printf("%.5f\n", f) // 3.14159
 
    // int to string
    s := strconv.Itoa(42)
    fmt.Println(s + " is the answer") // 42 is the answer
 
    // int64 to hex string
    hex := strconv.FormatInt(255, 16)
    fmt.Println(hex) // ff
}

In production

Always check the error from strconv functions - a 0 return on failure is the zero value, not a successfully parsed zero. ParseInt's bitSize parameter specifies the target type's range, not a cap on the input string; passing "200" with bitSize=8 returns an overflow error because 200 doesn't fit in an int8, but the string itself is still valid. Prefer strconv over fmt.Sscanf for number parsing: Sscanf is slower, less precise, and its error messages are harder to act on. In HTTP handlers that parse numeric path or query parameters, always validate with strconv at the boundary and return a 400 before the parsed value reaches business logic.

Enjoyed this? Get more essays on software craft delivered to your inbox.

Subscribe free