字符串易漏点

51 阅读1分钟

字符串是不可变字节(byte)序列,其本身是一个复合结构

type stringStruct struct {
    str unsafe.Pointer  //用于指针类型的转换
    len int
}

头部指针指向字节数组

内置函数len返回字节数组的长度,cap不接受字符串类型参数

性能

除类型外,动态构建字符串也容易造成性能问题

用加法操作符拼接字符串时,每次都须重新分配内存。如此,在构建“超大”字符串时,性能就显得极差。

改进思路是预分配足够的内存空间,常用方法是用string.Join函数,它会统计所有参数长度,并一次性完成内存分配操作。

func Join(elems []string, sep string) string {
   switch len(elems) {
   case 0:
      return ""
   case 1:
      return elems[0]
   }
   //统计分隔符长度
   n := len(sep) * (len(elems) - 1)
   //统计所有待拼接字符串长度
   for i := 0; i < len(elems); i++ {
      n += len(elems[i])
   }

   var b Builder
   b.Grow(n)
   b.WriteString(elems[0])
   //拷贝数据
   for _, s := range elems[1:] {
      b.WriteString(sep)
      b.WriteString(s)
   }
   return b.String()
}

bytes.Buffer也能完成类似操作