String 从字符串转换时如何确定[]符文的容量

String 从字符串转换时如何确定[]符文的容量,string,go,casting,rune,String,Go,Casting,Rune,有人能解释一下为什么我在[]符文中转换相同的字符串时得到不同的容量吗 看看这个代码 package main import ( "fmt" ) func main() { input := "你好" runes := []rune(input) fmt.Printf("len %d\n", len(input)) fmt.Printf("len %d\n&

有人能解释一下为什么我在
[]符文
中转换相同的
字符串时得到不同的容量吗

看看这个代码

package main

import (
    "fmt"
)

func main() {
    input := "你好"
            
    runes := []rune(input)

    fmt.Printf("len %d\n", len(input))
    fmt.Printf("len %d\n", len(runes))
    fmt.Printf("cap %d\n", cap(runes))

    fmt.Println(runes[:3])

}
哪个回报

len 6
len 2
cap 2
panic: runtime error: slice bounds out of range [:3] with capacity 2
但是当注释
fmt.Println(符文[:3])
时,它返回:

len 6
len 2
cap 32
查看[]符文容量是如何从2变为32的。怎样为什么?


如果您想测试=>

,只要转换的结果片包含输入字符串的符文,容量可能会更改为任何值。这是规范要求和保证的唯一内容。如果将其传递给
fmt.Println()
,编译器可能会决定使用较低的容量,因为这表示该片可能会转义。同样,编译器所做的决定不在您的掌控之中

Escape意味着值可能会从函数中逃逸,因此,必须在堆上(而不是堆栈上)分配该值,因为一旦函数返回,堆栈可能会被破坏/覆盖,如果值“逃逸”自函数,则只要有对该值的引用,就必须保留其内存区域。Go编译器执行转义分析,如果它不能证明某个值没有转义它在其中声明的函数,则该值将在堆上分配


参见相关问题:

字符串和
[]符文从
len
返回不同结果的原因是它在计算不同的东西
len(string)
返回字节长度(对于多字节字符,可能大于字符数),而
len([]符文)
返回符文片段的长度,这反过来就是UTF-8符文的数量(通常是字符数)


这篇博文详细介绍了Go是如何处理各种形式的文本的:

一个相关的线程,并在Go github问题跟踪器上进行了一些讨论,尽管来自Go 1.7:cap的值不是由规范指定的,任何足够大的值都可以。你能扩展一下“escape”是什么意思吗?嗯,我还没有想到过escape。对堆或堆栈进行不同的分配可能更有意义。谢谢,我知道。我的问题是关于能力。