NOTE
1.6 string
Character sets and Unicode, basic Go string usage, string/[]byte conversion, StringHeader, and string immutability.
This is a historical learning note and may contain outdated or incomplete understanding.
1. Character Sets
A computer can only store bytes (binary), so characters must also be stored using bytes. But how are they displayed after being stored? A mapping between bytes and characters is needed. This is a character set. For example:
1.1. Unicode Character Set
- Origin At first there was only the ASCII character set, which only supported English; GB2312 was introduced to support Simplified Chinese; BIG5 was introduced to support Traditional Chinese… There were too many standards and no unification, so Unicode appeared.
- Fixed-length encoding
- Variable-length encoding
- UTF-8 character set

2. What It Is
- A string encoded using Unicode.
3. Usage
3.1. Basic Usage
func TestString1(t *testing.T) {
s := "hello world"
fmt.Println(s, len(s))
s1 := s + "!"
fmt.Println(s1, len(s1))
s2 := s[:5]
fmt.Println(s2, len(s2))
for _, i := range s2 {
fmt.Println(i, string(i))
}
}
// output
hello world 11
hello world! 12
hello 5
104 h
101 e
108 l
108 l
111 o
3.2. Conversion Between string and []byte
- string to []byte
func str2bytes(s string) []byte {
p := make([]byte, len(s))
for i := 0; i < len(s); i++ {
c := s[i]
p[i] = c
}
return p
}
func TestString2(t *testing.T) {
fmt.Println(str2bytes("hello"))
}
// output
[104 101 108 108 111]
- []byte to string
func TestString3(t *testing.T) {
fmt.Println(bytes2str([]byte{104, 101, 108, 108, 111}))
}
func bytes2str(s []byte) (p string) {
data := make([]byte, len(s))
for i, c := range s {
data[i] = c
}
hdr := (*reflect.StringHeader)(unsafe.Pointer(&p))
hdr.Data = uintptr(unsafe.Pointer(&data[0]))
hdr.Len = len(s)
return p
}
// output
hello
4. Implementation
4.1. Data Structure
type StringHeader struct {
Data uintptr// the underlying byte array pointed to by the string
Len int// length of the string in bytes
}
4.1.1. How the End of a Character Sequence Is Determined
- C uses
'\0'to determine the character boundary, while Golang uses alengthfield.
4.1.2. The Underlying Storage Is an Immutable Byte Array
s := "test"
fmt.Println(s[1])
s[1] = 'c'// does not compile

4.1.2.1. Why It Is Immutable
s := "test"
s1 := s[1:]
- If
s1could be modified, it would affects, which could cause unpredictable consequences.


Discussion
Sign in with GitHub to comment. Discussions are stored as GitHub Issues.View on GitHub