Go

Compare strconv with fmt for number/string conversion. What do strconv.ParseInt's base and bitSize arguments do, and how do you check for range errors?

Question 545MediumGo 1.22 to 1.25

strconv is type-specific and does not allocate for parsing. It returns precise errors and is several times faster than fmt.Sprintf("%d") or fmt.Sscan, which go through reflection and interface boxing. For hot paths, use the strconv.Append* functions into a reused buffer. What does this print?

i := 65
fmt.Println(string(rune(i)))  // A      (string(i) on an int is a vet error: it's a rune conversion)
fmt.Println(strconv.Itoa(i))  // 65

n, err := strconv.ParseInt("300", 10, 8)
fmt.Println(n, err)           // 127 strconv.ParseInt: parsing "300": value out of range
fmt.Println(errors.Is(err, strconv.ErrRange)) // true

v, _ := strconv.ParseInt("0x_1F", 0, 64)
fmt.Println(v)                // 31  (base 0: prefix + underscores allowed)

_, err = strconv.Atoi("12a")
var ne *strconv.NumError
if errors.As(err, &ne) {
	fmt.Println(ne.Func, ne.Num, ne.Err) // Atoi 12a invalid syntax
}
  • base is 2 to 36, or 0 to infer it from the prefix (0x, 0o/0, 0b). Underscores are allowed only when base is 0.
  • bitSize (0 = int, 8, 16, 32, 64) is the range the result must fit in. The return type is always int64, so you still convert it with int8(n).
  • When the value is out of range, the result is clamped to the max or min value and err.Err == strconv.ErrRange. Always check the error, or the clamped value leaks into your program.

ParseFloat accepts "NaN", "Inf" and hex floats. FormatFloat(f, 'g', -1, 64) gives the shortest string that round-trips. Quote and Unquote handle Go string literals.

More on More Standard Library Essentials

All 16 More Standard Library Essentials questions