string 如何在Golang中将字符附加到字符串?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40310333/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 16:34:42  来源:igfitidea点击:

How to append a character to a string in Golang?

stringgoconcat

提问by cohadar

How to append a character to a string in Go?

如何在Go中将字符附加到字符串?

This does not work:

这不起作用:

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

invalid operation: s + c (mismatched types string and rune)

无效操作:s + c(字符串和符文类型不匹配)

This does not work either:

这也不起作用:

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

invalid operation: s + rune(c) (mismatched types string and rune)

无效操作:s + rune(c)(字符串和符文类型不匹配)

回答by cohadar

In Go rune type is nota character type, it is just another name for int32.

在 Go 中,符文类型不是字符类型,它只是 int32 的另一个名称。

If you come from Java or a similar language this will surprise you because Java has char type and you can add char to a string.

如果您来自 Java 或类似语言,这会让您感到惊讶,因为 Java 具有 char 类型,您可以将 char 添加到字符串中。

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

In Go you need to be more explicit:

在 Go 中,您需要更加明确:

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

Omg do you really need to convert every char to a string constant? Yes, but do not worry, this is just because of a type system and compiler optimizes it correctly. Under the hood both Java and Go append the char in the same manner.

天哪,您真的需要将每个字符转换为字符串常量吗?是的,但别担心,这只是因为类型系统和编译器正确优化了它。在底层,Java 和 Go 都以相同的方式附加字符。

If you think extra typing sucks, just compare how many times stringkeyword appears in each example above. :)

如果您认为额外的输入很糟糕,只需比较上面每个示例中string关键字出现的次数。:)

Extra info: (technical details)

额外信息:(技术细节)

In Go strings are notsequences of runes, they are utf-8encoded sequences of runes. When you range over a string you get runes, but you cannot simply append a rune to a string. For example: euro sign '' is an integer 0x20AC (this is called code point) But when you encode euro sign in utf-8 you get 3 bytes: 0xE2 0x82 0xAC http://www.fileformat.info/info/unicode/char/20aC/index.htm

在 Go 中,字符串不是符文序列,它们是utf-8编码的符文序列。当你跨越一个字符串时,你会得到符文,但你不能简单地将符文附加到一个字符串上。例如:欧元符号 '' 是一个整数 0x20AC(这称为代码点)但是当你用 utf-8 编码欧元符号时,你会得到 3 个字节:0xE2 0x82 0xAC http://www.fileformat.info/info/unicode/ char/20aC/index.htm

So appending a char actually works like this:

所以附加一个字符实际上是这样工作的:

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

Note that encodings are done at compile time.

请注意,编码是在编译时完成的。

Utf-8 can encode a character with 1, 2, 3, or 4 bytes. Utf-16 can encode a character with 2 or with 4 bytes.

utf-8 可以编码 1、2、3 或 4 个字节的字符。utf-16 可以用 2 个或 4 个字节编码一个字符。

So Go usually appends 1 byte (for ascii) or 2, 3, 4 bytes for Chinese, and Java usually appends 2 bytes (for ascii) or 4 bytes for Chinese.

所以Go通常为中文附加1个字节(对于ascii)或2、3、4个字节,而Java通常为中文附加2个字节(对于ascii)或4个字节。

Since most characters that we (west) use can be encoded with 2 bytes Java gives the false belief that strings are sequences of 2byte char-s, which is true until you need to encode 美国必须死

由于我们(西方)使用的大多数字符都可以用 2 个字节进行编码,Java 错误地认为字符串是 2 个字节的字符序列,这在您需要编码之前是正确的 美国必须死

回答by ashutosh

Simple but little inefficient

简单但有点低效

While this works perfectly fine for a simple program, But it is a little inefficient. Because strings in Go are immutable , so every time we want to change string or add to string then we are creating new string. For the scenario where we need to add multiple characters/strings to string, then it is inefficient

虽然这对于一个简单的程序来说非常有效,但它的效率有点低。因为 Go 中的字符串是不可变的,所以每次我们想要更改字符串或添加到字符串时,我们都会创建新的字符串。对于我们需要将多个字符/字符串添加到字符串中的场景,那么它是低效的

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

Using strings.Builder(Go 1.10+)

使用strings.Builder(Go 1.10+)

A Builder is used to efficiently build a string using Write methods. It minimizes memory copying. The zero value is ready to use. Do not copy a non-zero Builder.

Builder 用于使用 Write 方法有效地构建字符串。它最大限度地减少了内存复制。零值即可使用。不要复制非零的 Builder。

    package main

    import (
      "strings"
      "fmt"
    )

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