«Convert string to integer type in Go?» — вопрос, который мучает новичков
Каждый, кто начинал писать на Go, рано или поздно упирался в стену: нужно взять строку вида "42" и превратить её в честное число 42. Казалось бы, что может быть проще? Но именно этот вопрос на Stack Overflow собирает тысячи просмотров, а под ним — десятки комментариев с типичными ошибками. Почему так происходит?
В Go нет привычного по Python или JavaScript int("42"). Вместо этого — мощный, но строгий пакет strconv, который заставляет вас думать о том, что может пойти не так. И это правильно: вы не можете просто «прокинуть» строку в int, потому что строка может оказаться битой, пустой или содержать лишние пробелы.
В этой статье мы разберём конвертацию строки в число в Go на реальных примерах, пройдёмся по граблям, на которые наступают даже опытные разработчики, и дадим рабочие шаблоны кода. Поехали!
1. Главный инструмент: пакет strconv
В стандартной библиотеке Go за преобразование строк отвечает пакет strconv. У него есть три основных функции для перевода строки в целое число:
Atoi(s string) (int, error)— самый простой вариант, конвертирует строку вint(разрядность зависит от платформы: 32 или 64 бита).ParseInt(s string, base int, bitSize int) (int64, error)— даёт полный контроль: база системы счисления (10, 16, 2) и разрядность (0, 8, 16, 32, 64).ParseUint(s string, base int, bitSize int) (uint64, error)— то же самое, но для беззнаковых чисел.
Самая популярная ошибка — игнорирование возвращаемой ошибки. Давайте посмотрим, к чему это приводит.
Пример 1: Игнорируем ошибку — получаем баг
package main
import (
"fmt"
"strconv"
)
func main() {
s := "123abc"
num, _ := strconv.Atoi(s) // Ошибка проглочена!
fmt.Println(num) // Вывод: 0 — и вы даже не узнаете, что пошло не так
}
В Go нет исключений, ошибка — это значение. Если вы её проигнорируете (_), вы получите нулевое значение (0) и потратите часы на дебаг, гадая, почему ваша программа ведёт себя странно. Всегда обрабатывайте ошибку!
2. Топ-5 ошибок при конвертации string в int в Golang
Мы проанализировали вопросы на Stack Overflow и выделили самые частые проблемы. Вот они:
Ошибка №1: Пробелы и невидимые символы
Строка " 42 " или "42\n" — Atoi вернёт ошибку. Go не терпит лишних символов, в отличие от некоторых языков, которые автоматически тримят строку.
s := " 42 "
num, err := strconv.Atoi(s)
if err != nil {
fmt.Println("Ошибка:", err) // strconv.Atoi: parsing " 42 ": invalid syntax
}
Решение: используйте strings.TrimSpace() перед конвертацией.
import "strings"
s := " 42 "
s = strings.TrimSpace(s)
num, err := strconv.Atoi(s)
if err == nil {
fmt.Println(num) // 42
}
Ошибка №2: Пустая строка
Пустая строка "" — тоже ошибка. Многие новички ожидают, что пустая строка превратится в 0, но это не так.
num, err := strconv.Atoi("")
// err: strconv.Atoi: parsing "": invalid syntax
Решение: проверяйте длину строки или обрабатывайте ошибку явно, подставляя значение по умолчанию.
Ошибка №3: Переполнение (overflow)
Если строка содержит число, которое не влезает в выбранный тип, Atoi или ParseInt вернут ошибку ErrRange и максимальное/минимальное значение для данного типа.
s := "99999999999999999999" // больше, чем int64
num, err := strconv.ParseInt(s, 10, 64)
if err != nil {
fmt.Println(err) // strconv.ParseInt: parsing "99999999999999999999": value out of range
}
Решение: выбирайте правильный bitSize. Если вы не знаете разрядность, используйте Atoi (он подстраивается под архитектуру) или ParseInt(s, 10, 64) и потом проверяйте диапазон.
Ошибка №4: Неверная система счисления
Вы ожидаете десятичное число, а в строке — шестнадцатеричное "0xFF". Atoi такое не переварит, а ParseInt — да, если указать base: 0 (автоопределение).
// Atoi — ошибка
num, err := strconv.Atoi("0xFF") // invalid syntax
// ParseInt с base 0 — работает
num, err := strconv.ParseInt("0xFF", 0, 64)
if err == nil {
fmt.Println(num) // 255
}
Совет: если вы ждёте числа только в десятичной системе, всегда передавайте base: 10.
Ошибка №5: Локализованные форматы (запятые, пробелы)
Строка "1,234" или "1 234" — это не число для Go. Нужно предварительно удалить разделители.
s := "1,234"
s = strings.ReplaceAll(s, ",", "")
num, err := strconv.Atoi(s)
if err == nil {
fmt.Println(num) // 1234
}
3. Правильный шаблон для конвертации string в int
Чтобы избежать всех этих ошибок, используйте единый подход. Вот рекомендуемый шаблон, который можно вставить в любой проект:
package main
import (
"fmt"
"strconv"
"strings"
)
// SafeAtoi конвертирует строку в int с обработкой типичных проблем.
func SafeAtoi(s string) (int, error) {
// 1. Убираем пробелы
s = strings.TrimSpace(s)
// 2. Проверяем на пустую строку
if s == "" {
return 0, fmt.Errorf("пустая строка")
}
// 3. Конвертируем
num, err := strconv.Atoi(s)
if err != nil {
return 0, fmt.Errorf("неверный формат числа: %s", s)
}
return num, nil
}
func main() {
tests := []string{"42", "