插件窝 干货文章 Go语言字符串:真的是由单个字节连接的吗?

Go语言字符串:真的是由单个字节连接的吗?

字节 字符串 字符 UTF-8 647    来源:    2025-03-16

在Go语言中,字符串并不是由单个字节简单连接而成的。Go语言的字符串是由一系列不可变的字节(byte)组成的,这些字节通常表示UTF-8编码的字符。UTF-8是一种可变长度的字符编码,这意味着一个字符可能由1到4个字节组成。

字符串的内部表示

在Go语言中,字符串的内部表示是一个结构体,包含两个字段: 1. 一个指向字节数组的指针。 2. 一个表示字节数组长度的整数。

type stringStruct struct {
    str unsafe.Pointer
    len int
}

字符串的不可变性

Go语言中的字符串是不可变的,这意味着一旦创建了一个字符串,就不能修改它的内容。任何对字符串的修改操作(如拼接、替换等)都会生成一个新的字符串。

示例

package main

import (
    "fmt"
)

func main() {
    s := "Hello, 世界"
    fmt.Println(len(s)) // 输出: 13
    fmt.Println(s[0])    // 输出: 72 (ASCII码中的'H')
    fmt.Println(s[7])    // 输出: 228 (UTF-8编码中'世'的第一个字节)
}

在这个例子中,字符串 s 包含了英文字符和中文字符。len(s) 返回的是字节长度,而不是字符长度。因为中文字符在UTF-8编码中通常占用3个字节,所以 len(s) 返回13。

字符与字节的区别

  • 字节(byte):是存储和传输数据的基本单位,通常是一个8位的二进制数。
  • 字符(rune):在Go语言中,runeint32 的别名,用于表示一个Unicode码点。一个字符可能由多个字节组成。

遍历字符串

如果你需要遍历字符串中的每个字符(而不是每个字节),可以使用 range 关键字:

package main

import (
    "fmt"
)

func main() {
    s := "Hello, 世界"
    for i, r := range s {
        fmt.Printf("%d: %c\n", i, r)
    }
}

在这个例子中,range 会逐个字符遍历字符串,rrune 类型的字符,i 是该字符的起始字节索引。

总结

Go语言中的字符串是由字节组成的,但这些字节通常是UTF-8编码的字符。字符串是不可变的,且一个字符可能由多个字节组成。因此,字符串并不是由单个字节简单连接而成的,而是由一系列字节组成的,这些字节表示UTF-8编码的字符。