String 如何在Golang中向字符串追加字符?

String 如何在Golang中向字符串追加字符?,string,go,concat,String,Go,Concat,如何在Go中向字符串追加字符 这不起作用: s := "hello"; c := 'x'; fmt.Println(s + c); 无效操作:s+c(字符串和符文类型不匹配) 这也不起作用: s := "hello"; c := 'x'; fmt.Println(s + rune(c)); 无效操作:s+rune(c)(字符串和rune类型不匹配)在Go中,rune类型不是字符类型,它只是int32的另一个名称 如果您来自Java或类似的语言,这会让您感到惊讶,因为Java有char类型

如何在Go中向字符串追加字符

这不起作用:

s := "hello";
c := 'x'; 
fmt.Println(s + c);
无效操作:s+c(字符串和符文类型不匹配)

这也不起作用:

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

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

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

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

String s = "hello";
char c = 'x';
System.out.println(s + c);
在围棋中,你需要更加明确:

s := "hello";
c := 'x';
fmt.Println(s + string(c));
天哪,你真的需要把每个字符转换成字符串常量吗?是的,但不要担心,这只是因为类型系统和编译器正确地优化了它。在引擎盖下,Java和Go都以相同的方式附加字符

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

额外信息:(技术细节)

围棋中的字符串不是符文序列,而是符文编码序列。当你跨越一个字符串时,你会得到符文,但你不能简单地将符文附加到一个字符串上。 例如:欧元符号“€”是一个整数0x20AC(这称为代码点) 但在utf-8中对欧元符号进行编码时,会得到3个字节:0xE2 0x82 0xAC

因此,添加字符实际上是这样工作的:

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个字节(对于中文)


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

简单但效率低

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

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

生成器用于使用写方法高效地构建字符串。它最大限度地减少了内存复制。零值已准备好使用。不要复制非零生成器

    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())
    }

您是否同时发布了问题和答案?为什么?因为我之前找不到关于堆栈溢出的答案,而谷歌给出了糟糕的结果。这是一种标准做法。我相信通常的做法是在你不知道答案的时候提问。@slomek如果你单击“提问”,你会看到一个复选框来回答你自己的问题。事实上,这是由提问页面链接而来的,@Tinwor所写的正是我的意思。回答你自己的问题是可以的,但是如果你已经有了答案,那么问一个问题是没有意义的。如果你发布了它,然后研究了它并提出了一些解决方案,我不会介意。go字符串是一个字节序列,而不是符文。在字符串上进行测距隐式返回符文以及字符串中的字节索引。实际上不是这样,因为不是每个字节序列都是有效字符串。它们可以类型转换成字节序列。不,我保证它们是(没有类型转换,只有转换)。字符串数据结构仅由字节数组和该数组的长度组成。range操作符扫描符文,但字符串仍然是字节。
字符串
[]字节
类型具有相同的基础数据,可以在两个方向上进行转换@科哈达尔:这显示了字节索引,这正是我在评论中所说和演示的。没有
范围
的情况下,同样的情况如下:(为了更好地衡量,
[]字节
也是等效的)@JimB是的,你是对的。我只是想指出,即使你“在引擎盖下”有些东西是一样的,并不意味着类型是一样的。例如,int32和unit32在引擎盖下是相同的,但在符号操作或打印时表现不同。与int32和rune相比,它们在值和类型(别名)上都是相同的。我有点困惑,因为您的代码在Go Playerd上并不真正起作用。例如,
r
来自哪里?
s
c
的声明在语法上不是有效的Go(除非我遗漏了什么),而是可疑地类似于Java。也许你想要这样的东西:?@Gwynethlewelyn是的,你是对的,我的错。更正的代码语法