Преобразование типов и strconv

Go не делает неявных преобразований. Если нужно из string получить int - нужно сказать это явно. Это защищает от багов, но нужно знать как. Основы про типы - в уроке Переменные и типы без паники.

Преобразование между числовыми типами

var x int = 42
var y float64 = float64(x)  // int → float64
var z int32 = int32(x)       // int → int32

// Потеря данных при сужении типа!
var big int64 = 1_000_000
var small int8 = int8(big) // overflow: -64
При преобразовании большого типа в маленький (int64 → int8) Go не предупреждает! Данные молча обрезаются. Проверяй границы сам.

Строка ↔ Число: пакет strconv

Это главный пакет для преобразования строк в числа и обратно.

Строка → Число

import "strconv"

// Строка → int
num, err := strconv.Atoi("42")
if err != nil {
    fmt.Println("Ошибка:", err)
}
fmt.Println(num) // 42

// Строка → int64 (с указанием основания и разрядности)
num64, err := strconv.ParseInt("FF", 16, 64)
fmt.Println(num64) // 255

// Строка → float64
price, err := strconv.ParseFloat("99.99", 64)
fmt.Println(price) // 99.99

// Строка → bool
flag, err := strconv.ParseBool("true")
fmt.Println(flag) // true

Число → Строка

// int → строка
s := strconv.Itoa(42)
fmt.Println(s) // "42"

// float → строка
s2 := strconv.FormatFloat(3.14159, 'f', 2, 64)
fmt.Println(s2) // "3.14"

// Через fmt.Sprintf (универсальный способ)
s3 := fmt.Sprintf("%d", 42)
s4 := fmt.Sprintf("%.2f", 3.14)
s5 := fmt.Sprintf("%t", true)

<ComparisonTable data={{ headers: ["Задача", "Функция", "Пример"], rows: [ ["string → int", "strconv.Atoi", "Atoi("42") → 42"], ["int → string", "strconv.Itoa", "Itoa(42) → "42""], ["string → float64", "strconv.ParseFloat", "ParseFloat("3.14", 64) → 3.14"], ["string → int64", "strconv.ParseInt", "ParseInt("FF", 16, 64) → 255"], ["string → bool", "strconv.ParseBool", "ParseBool("true") → true"], ["любой → string", "fmt.Sprintf", "Sprintf("%d", 42) → "42""] ] }} />

Обработка ошибок преобразования

Преобразование может не удаться - всегда проверяй error (подробнее - в уроке Обработка ошибок):

inputs := []string{"42", "hello", "3.14", "", "-7"}

for _, s := range inputs {
    num, err := strconv.Atoi(s)
    if err != nil {
        fmt.Printf("  %q - ошибка: %v\n", s, err)
    } else {
        fmt.Printf("  %q → %d\n", s, num)
    }
}
// "42" → 42
// "hello" - ошибка: strconv.Atoi: parsing "hello": invalid syntax
// "3.14" - ошибка: strconv.Atoi: parsing "3.14": invalid syntax
// "" - ошибка: strconv.Atoi: parsing "": invalid syntax
// "-7" → -7

Строка ↔ Байты

// string → []byte
s := "Привет"
b := []byte(s)
fmt.Println(b) // [208 159 209 ...]

// []byte → string
s2 := string(b)
fmt.Println(s2) // Привет

// int → rune → string
r := rune(65)
fmt.Println(string(r)) // A
В Go строка - это неизменяемая последовательность байтов. `[]byte` - изменяемая копия. Конвертация создаёт копию данных.

Практический пример: парсинг конфига

func parseConfig(lines []string) map[string]interface{} {
    config := make(map[string]interface{})

    for _, line := range lines {
        parts := strings.SplitN(line, "=", 2)
        if len(parts) != 2 {
            continue
        }

        key := strings.TrimSpace(parts[0])
        val := strings.TrimSpace(parts[1])

        // Пробуем разные типы
        if i, err := strconv.Atoi(val); err == nil {
            config[key] = i
        } else if f, err := strconv.ParseFloat(val, 64); err == nil {
            config[key] = f
        } else if b, err := strconv.ParseBool(val); err == nil {
            config[key] = b
        } else {
            config[key] = val // оставляем как строку
        }
    }

    return config
}

// port=8080       → int 8080
// rate=0.5        → float64 0.5
// debug=true      → bool true
// host=localhost   → string "localhost"

Типичные ошибки

// ОШИБКА: string(число) - это не то, что ты думаешь!
fmt.Println(string(65))  // "A" (Unicode символ), НЕ "65"!
fmt.Println(strconv.Itoa(65)) // "65" - правильно

// ОШИБКА: забыть проверить err
num, _ := strconv.Atoi(userInput) // если "abc" → num будет 0 без ошибки!

Зарегистрируйтесь бесплатно, чтобы пройти квиз, решить задание с автопроверкой и вести прогресс.