携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情
操作字符串离不开字符串的拼接,字符串拼接在go里面有很多种实现,但是Go中string是只读类型,大量字符串的拼接会造成性能问题。本文主要介绍一下go语言中常用的五种字符串拼接方式以及性能,感兴趣的小伙伴可以参考一下。
+拼接方式
php使用.拼接,go语言中用+拼接,这种方式是最常用的也是最简单的,不过由于golang中字符串是不可变得类型,因此用+拼接会产生一个新的字符串对效率有影响。
func main(){
s1 := "good"
s2 := "morning"
s3 := s1 + " " +s2
fmt.Println(s3) // good morning
}
fmt.Sprintf函数
这种方式也是开发过程中经常使用到的,这种写的好处是不会直接产生临时字符串,但是效率也不是特别高。
s1 := "good"
s2 := "morning"
s3 := fmt.Sprintf("%s %s", s1, s2)
fmt.Println(s3) // good morning
strings.Join函数
使用Join函数我们需要先引入strings包才可以,Join函数会先根据字符串数组的内容,计算出一个拼接之后的长度,然后申请对应大小的内存,一个一个字符串填入,在已有一个数组的情况下,这种效率会很高,如果没有的话效率也不高,一般常用于切片转为字符串。
s1 := "good"
s2 := "morning"
str := []string{s1, s2}
s3 := strings.Join(str, "")
fmt.Println(s3) // good morning
buffer.Builderbuffer.WriteString函数
因为string类型底层就是一个byte数组,所以我们就可以Go语言的bytes.Buffer进行字符串拼接。
bytes.buffer是一个缓冲byte类型的缓冲器,存放着都是byte,是一个变长的 buffer,具有 Read 和Write 方法。 buffer 的 零值 是一个 空的 buffer,但是可以使用,底层就是一个 []byte, 字节切片。
效率比上面的高不少但是我在开发中基本上没有用过。
s1 := "good"
s2 := "morning"
var buf bytes.Buffer
buf.WriteString(s1)
buf.WriteString(s2)
s3 := buf.String()
fmt.Println(s3) // goodmorning
向Buffer中写数据,可以看出Buffer中有个Grow函数用于对切片进行扩容。
func (b *Buffer) WriteString(s string) (n int, err error) {
b.lastRead = opInvalid
m, ok := b.tryGrowByReslice(len(s))
if !ok {
m = b.grow(len(s))
}
return copy(b.buf[m:], s), nil
}
buffer.Builder函数
官方建议使用的的拼接方式,string.Builder 通过使用一个内部的 slice 来存储数据片段。当开发者调用写入方法的时候,数据实际上是被追加(append)到了其内部的 slice 上。
func (b *Builder) WriteString(s string) (int, error) {
b.copyCheck()
b.buf = append(b.buf, s...)
return len(s), nil
}
示例:
s1 := "good"
s2 := "morning"
var build strings.Builder
build.WriteString(s1)
build.WriteString(s2)
s3 := build.String()
fmt.Println(s3) // goodmorning
bytes.Buffer 是重新申请了一块空间,存放生成的string变量, 而strings.Builder直接将底层的[]byte转换成了string类型返回了回来,去掉了申请空间的操作。所以strings.Builder效率比bytes.Buffer高。
总结
- 性能要求不太高的场景,直接使用运算符
+,代码更简短清晰,有较好的可读性 - 如果需要拼接的不仅仅是字符串,还有数字之类的其他需求的话,可以用
fmt.Sprintf() - 在已有字符串数组的场合,使用
strings.Join()有比较好的性能 - 在一些性能要求较高的场合,尽量使用
buffer.WriteString()以获得更好的性能