Конвертация строки в число в Go: 5 ловушек и их решение

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

«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", "                

Блоги

Рекомендаций по книгам