Как в Go можно заменить символ в строке? Почему нельзя изменить строку напрямую?

Ответ

В Go строки иммутабельны (неизменяемы). Это означает, что после создания строки изменить ее содержимое напрямую (например, по индексу) нельзя. Это сделано для безопасности и производительности (например, строки можно безопасно передавать между горутинами без блокировок).

Чтобы изменить строку, нужно создать новую на основе старой. Основные способы:

  1. Преобразование в срез рун ([]rune) Это основной способ для замены символа по индексу. Он корректно работает с Unicode (многобайтовыми символами).

    s := "привет"
    runes := []rune(s)
    runes[0] = 'П' // Заменяем 'п' на 'П'
    result := string(runes) // "Привет"

    Использование []byte вместо []rune опасно, так как один символ кириллицы занимает несколько байт, и вы повредите данные.

  2. Использование strings.Replace или strings.ReplaceAll Подходит для замены всех вхождений одной подстроки на другую.

    s := "hello, world!"
    // Заменить первое вхождение "l" на "x"
    result1 := strings.Replace(s, "l", "x", 1) // "hexlo, world!"
    
    // Заменить все вхождения "l" на "x"
    result2 := strings.ReplaceAll(s, "l", "x") // "hexxo, worxd!"
  3. Использование strings.Builder Это самый эффективный способ для построения строк по частям, особенно в циклах. Он работает быстрее, чем конкатенация + или bytes.Buffer.

    var builder strings.Builder
    s := "hello"
    for _, r := range s {
        if r == 'l' {
            builder.WriteRune('x')
        } else {
            builder.WriteRune(r)
        }
    }
    result := builder.String() // "hexxo"