2

我正在从 C 背景自学 Go。下面的代码按我的预期工作(前两个Printf()将访问字节,后两个Printf()将访问代码点)。

我不清楚的是这是否涉及任何数据复制。

package main

import "fmt"

var a string

func main() {
    a = "èe"
    fmt.Printf("%d\n", a[0])
    fmt.Printf("%d\n", a[1])
    fmt.Println("")
    fmt.Printf("%d\n", []rune(a)[0])
    fmt.Printf("%d\n", []rune(a)[1])
}

换句话说:

确实会[]rune("string")创建一个符文数组并用对应的符文填充它"string",还是只是编译器弄清楚如何从字符串字节中获取符文?

4

2 回答 2

6

在不分配数组的情况下,不可能将 []uint8(即字符串)转换为 []int32([]rune 的别名)。

此外,字符串在 Go 中是不可变的,但切片不是,因此转换为 []byte 和 []rune 必须以某种方式复制字符串的字节。

于 2021-07-12T11:37:49.253 回答
4

它涉及副本,因为:

  • 字符串是不可变的;如果转换[]rune(s)没有复制,您将能够索引符文切片并更改字符串内容
  • string值是“ (可能为空)字节序列”,其中byte是 的别名uint8,而 arune“标识 Unicode 代码点的整数值”和 的别名int32。类型不相同,甚至长度也可能不同:
    a = "èe"
    r := []rune(a)
    fmt.Println(len(a)) // 3 (3 bytes)
    fmt.Println(len(r)) // 2 (2 Unicode code points)
于 2021-07-12T11:50:38.820 回答