忆梦|我擦~字符串转字节切片后,切片的容量竟然千奇百怪( 四 )


我们分析这块代码发现,go编译器在将字符串转字节切片生成AST时 , 总共分为三步 。

  1. 先判断该变量是否是常量字符串,如果是常量字符串,则直接通过types.NewArray创建一个和字符串等长的数组
  2. 常量字符串生成的切片变量也要进行逃逸分析 , 并判断其大小是否大于函数栈允许分配给变量的最大长度 ,从而判断节点是分配在栈上还是在堆上
  3. 最后 , 如果字符串长度是大于0 ,将字符串内容复制到字节切片中 ,然后返回 。 因此现象三中的切片容量是3也就完全清楚了
结论字符串转字节切片步骤如下
  1. 判断是否是常量 ,如果是常量则转换为等容量等长的字节切片
  2. 如果是变量 ,先判断生成的切片是否发生变量逃逸
  3. 如果逃逸或者字符串长度>32 ,则根据字符串长度可以计算出不同的容量
  4. 如果未逃逸且字符串长度<=32, 则字符切片容量为32
扩展常见逃逸情况
  1. 函数返回局部指针
  2. 栈空间不足逃逸
  3. 动态类型逃逸, 很多函数参数为interface类型 , 比如fmt.Println(a ...interface{}) , 编译期间很难确定其参数的具体类型, 也会发生逃逸
  4. 闭包引用对象逃逸
注: 写本文时 ,笔者所用go版本为: go1.13.4
【忆梦|我擦~字符串转字节切片后,切片的容量竟然千奇百怪】生命不息 ,探索不止 ,后续将持续更新有关于go的技术探索


推荐阅读