Как добавить символ в строку в Голанге?
Как добавить символ в строку в 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())
}