3.5. The string

A string is an immutable sequence of bytes. Strings can contain arbitrary data, including the byte value 0, but are generally used to contain human-readable text. Text strings are often interpreted as sequences of Unicode code points (RUNe) encoded in UTF8, which we’ll discuss in more detail later.

The built-in len function returns the number of bytes in a string (not rune characters), and the index s[I] returns the value of the ith byte. I must satisfy the 0 ≤ I < len(s) condition.

s := "hello, world"
fmt.Println(len(s)) / / "12"
fmt.Println(s[0], s[7]) // "104 119" ('h' and 'w')
Copy the code

Attempting to access bytes beyond the string index will result in a Panic exception:

c := s[len(s)] // panic: index out of range
Copy the code

The i-th byte is not necessarily the i-th character of the string, because UTF8 encoding for non-ASCII characters requires two or more bytes. Let’s talk a little bit about how characters work.

The substring operation s[I :j] generates a new string from the i-th byte of the original s-string to the JTH byte (not including j itself). The generated new string will contain j-i bytes.

fmt.Println(s[0:5]) // "hello"
Copy the code

Also, if the index is out of the string range or j is less than I, a panic exception will occur. Both I and j can be ignored, and when they are ignored 0 is used as the starting position and len(s) as the ending bit.

fmt.Println(s[:5]) // "hello"
fmt.Println(s[7:)// "world"
fmt.Println(s[:]) // "hello, world"
Copy the code

The + operator constructs a new string by linking two strings:

fmt.Println("goodbye" + s[5:)// "goodbye, world"
Copy the code

Strings can be compared with == and <; The comparison is done byte-by-byte, so the result of the comparison is the natural encoding order of strings.

String values are immutable: the sequence of bytes contained in a string is never changed, but we can also assign a new string value to a string variable. You can append one string to another as follows:

s := "left foot"
t := s
s += ", right foot"
Copy the code

This does not cause the original string value to be changed, but the variable S will hold a new string value due to the += statement, while t will still contain the original string value.

fmt.Println(s) // "left foot, right foot"
fmt.Println(t) // "left foot"
Copy the code

Since strings are immutable, attempts to modify data inside a string are also prohibited:

s[0] = 'L' // compile error: cannot assign to s[0]
Copy the code

Immutability means that two strings are safe if they share the same underlying data, making it cheap to copy strings of any length. Similarly, operations on a string S and the corresponding substring slice s[7:] can safely share the same memory, so the string slice operation is also cheap. There is no need to allocate new memory in either case. Figure 3.4 illustrates that a string and two substrings share the same underlying data.