How to append a character to a string in Golang?

huangapple go评论78阅读模式
英文:

How to append a character to a string in Golang?

问题

如何在Go语言中将字符追加到字符串中?

以下方法是无效的:

s := "hello"
c := 'x'
fmt.Println(s + c)
// invalid operation: s + c (mismatched types string and rune)

以下方法也是无效的:

s := "hello"
c := 'x'
fmt.Println(s + rune(c))
// invalid operation: s + rune(c) (mismatched types string and rune)

正确的方法是使用字符串拼接操作符+将字符转换为字符串后再进行拼接。可以使用string()函数将字符转换为字符串,然后再进行拼接,如下所示:

s := "hello"
c := 'x'
fmt.Println(s + string(c))
// 输出:hellox

这样就可以将字符追加到字符串中了。

英文:

How to append a character to a string in Go?

This does not work:

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

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

This does not work either:

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

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

答案1

得分: 96

在Go语言中,rune类型不是字符类型,它只是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));

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

如果你认为额外的输入很烦人,只需比较一下上面每个示例中出现的string关键字的次数即可。 How to append a character to a string in Golang?

额外信息:(技术细节)

在Go中,字符串不是rune的序列,它们是utf-8编码的rune序列。当你遍历一个字符串时,你会得到runes,但你不能简单地将一个rune追加到字符串中。
例如:欧元符号'€'是一个整数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个字节来编码一个字符。

因此,对于大多数我们(西方人)使用的字符,Java给出了一个错误的观念,即字符串是由2字节的char序列组成的,这在你需要编码"美国必须死"时是不正确的。

英文:

In Go rune type is not a character type, it is just another name for 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.

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

In Go you need to be more explicit:

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.

If you think extra typing sucks, just compare how many times string keyword appears in each example above. How to append a character to a string in Golang?

Extra info: (technical details)

In Go strings are not sequences of runes, they are utf-8 encoded 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

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.

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.

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

得分: 13

简单但效率稍低

虽然这个简单程序可以正常工作,但效率稍低。因为Go中的字符串是不可变的,所以每次我们想要改变字符串或向字符串添加内容时,都会创建一个新的字符串。对于需要向字符串添加多个字符/字符串的情况,这是低效的。

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

使用 strings.Builder(Go 1.10+)

使用 Builder 可以高效地构建字符串,它使用 Write 方法来最小化内存复制。零值即可使用,不要复制非零的 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())
}
英文:

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

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

Using 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.

    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

huangapple
  • 本文由 发表于 2016年10月29日 01:31:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/40310333.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定