How to append a character to a string in Golang?

StringGoConcat

String Problem Overview


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)

String Solutions


Solution 1 - String

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. :)

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 美国必须死

Solution 2 - 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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncohadarView Question on Stackoverflow
Solution 1 - StringcohadarView Answer on Stackoverflow
Solution 2 - StringashutoshView Answer on Stackoverflow