Как добавить символ в строку в Голанге?

Как добавить символ в строку в Go?

Это не работает:

s := "hello";
c := 'x'; 
fmt.Println(s + c);

недопустимая операция: s + c (несоответствие типов строки и руны)

Это тоже не работает:

s := "hello";
c := 'x'; 
fmt.Println(s + rune(c));

недопустимая операция: s + rune(c) (несоответствие типов строки и руны)

1 ответ

В Go тип рун не является символьным типом, это просто другое имя для int32.

Если вы пришли из Java или подобного языка, это вас удивит, потому что Java имеет тип char и вы можете добавить char в строку.

String s = "hello";
char c = 'x';
System.out.println(s + c);

В Go вы должны быть более явными:

s := "hello";
c := 'x';
fmt.Println(s + string(c));

OMG вам действительно нужно преобразовать каждый символ в строковую константу? Да, но не волнуйтесь, это просто из-за системы типов, и компилятор правильно ее оптимизирует. Под капотом Java и Go добавляют символ одинаково.

Если вы думаете, что лишняя типизация - отстой, просто сравните, сколько раз строковое ключевое слово появляется в каждом примере выше.:)

Дополнительная информация: (технические данные)

Строки в Go не являются последовательностями рун, они представляют собой последовательности рун в кодировке utf-8. Когда вы пробегаете строку, вы получаете руны, но вы не можете просто добавить руну к строке. Например: знак евро '€' является целым числом 0x20AC (это называется кодовой точкой). Но когда вы кодируете знак евро в utf-8, вы получите 3 байта: 0xE2 0x82 0xAC http://www.fileformat.info/info/unicode/char/20aC/index.htm

Таким образом, добавление символа на самом деле работает так:

s = append(s, encodeToUtf8(c)) // Go
s = append(s, encodeToUtf16(c)) // Java

Обратите внимание, что кодирование выполняется во время компиляции.

Utf-8 может кодировать символ длиной 1, 2, 3 или 4 байта. Utf-16 может кодировать символ с 2 или 4 байтами.

Поэтому Go обычно добавляет 1 байт (для ascii) или 2, 3, 4 байта для китайского, а Java обычно добавляет 2 байта (для ascii) или 4 байта для китайского.

Поскольку большинство символов, которые мы (западные) используем, могут быть закодированы с 2 байтами, Java дает ложное убеждение, что строки являются последовательностями 2-байтовых символов, что верно до тех пор, пока вам не нужно кодировать 美 need 必须死

Просто, но немного неэффективно

Хотя это отлично работает для простой программы, но это немного неэффективно. Поскольку строки в Go неизменяемы, поэтому каждый раз, когда мы хотим изменить строку или добавить к строке, мы создаем новую строку. Для сценария, когда нам нужно добавить несколько символов / строк в строку, это неэффективно.

s := "hello";
c := 'x';
fmt.Println(s + string(c));

Использование strings.Builder (Go 1.10+)

Построитель используется для эффективного построения строки с использованием методов записи. Это минимизирует копирование памяти. Нулевое значение готово к использованию. Не копируйте ненулевой Builder.

    package main

    import (
      "strings"
      "fmt"
    )
    
    func main() {
        var s string
        s = "hello";
        var c = 'x';
        var sb strings.Builder
        sb.WriteString(s)
        sb.WriteRune(c)
        fmt.Println(sb.String())
    }

https://play.golang.org/p/n1plG9eOxHD

Другие вопросы по тегам