拼接字符串的方式有: + 、fmt.Sprintf、strings.Builder、bytes.Buffer、strings.Join
+
使用 + 操作符进行拼接时,会对字符串进行遍历,计算并开辟一个新的空间来存储原来的两个字符串。
fmt.Sprintf
由于采用了接口参数,必须要用反射获取值,因此有性能损耗
strings.Builder
用WriterString()进行拼接,内部实现是指针+切片,同时String()返回拼接后的字符串,它是直接把[]byte转换为string,从而避免拷贝。
bytes.Buffer
bytes.Buffer 是一个一个缓冲byte类型的缓冲器,这个缓冲器里存放的都是byte,
bytes.Buffer 底层也是一个 []byte 切片
strings.join
strings.join 也是基于 strings.builder 来实现的,并且可以自定义分隔符,在join方法内调用了b.Grow(n)方法,这个是进行初步的容量分配,而前面计算的 n 的长度就是我们要拼接的 slice的长度,因为我们传入切片长度固定,所以提前进行容量分配可以减少内存分配,很高效。
性能比较
strings.Join = strings.Builder > bytes.Buffer > + > fmt.Sprintf
示例代码
func main(){
a := []string{"a", "b", "c"}
//方式1:+
ret := a[0] + a[1] + a[2]
//方式2:fmt.Sprintf
ret := fmt.Sprintf("%s%s%s", a[0],a[1],a[2])
//方式3:strings.Builder
var sb strings.Builder
sb.WriteString(a[0])
sb.WriteString(a[1])
sb.WriteString(a[2])
ret := sb.String()
//方式4:bytes.Buffer
buf := new(bytes.Buffer)
buf.Write(a[0])
buf.Write(a[1])
buf.Write(a[2])
ret := buf.String()
//方式5:strings.Join
ret := strings.Join(a,"")
}