Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > Go字符串拼接

一篇带你看懂Go语言中的字符串拼接(小白入门)

作者:却尘

这篇文章主要为大家详细介绍了Go语言中进行字符串拼接的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

在 Go 里:

字符串 string 是不可变的(你不能在原来的 string 上直接改)

所以 + / += 反复拼接,经常会很慢(反复分配 + 复制)

为了快,Go 常用两种方式:

cap / Grow 都是在做同一件事:提前预留容量,减少扩容拷贝

1. 为什么“拼字符串”会出问题?

你想要构造一个输出,比如:

"blue is sky the"

最直觉的写法是:

ans := ""
ans += "blue"
ans += " "
ans += "is"

看起来很合理对吧?

但 Go 的 string 有个关键特性:

Go 的 string 不可变(immutable)

你一旦创建了一个 string,它里面的内容不能“原地修改”。

所以 ans += "blue" 实际发生的是:

也就是说:每一次 += 都可能要“重新开数组 + 复制一遍旧内容”

2. 这就是为什么+会慢:重复拷贝

举个特别直观的例子:

你要拼 3 次:

你会发现:旧内容一直在被反复复制。

拼得越多,复制越多,速度就越慢。

3. 那怎么快?核心思路:用“可变容器”先装起来

既然 string 不可变,那我们先用一个 可变的容器 装字符,最后一次性变成 string。

Go 最常用的可变容器就是:

[]byte(字节数组 / 可变)

你可以对它 append,它会自动增长:

ans := make([]byte, 0)
ans = append(ans, 'b', 'l', 'u', 'e')

最后:

return string(ans)

这样就避免了每次 += 的“重新分配 + 复制旧内容”。

4. 这就引出了:len和cap是啥?

[]byte / []int 这些 slice,在 Go 里有两个重要概念:

比如:

ans := make([]byte, 0, 10)

意思是:

为什么要 cap?

因为如果你不预留,append 可能会这样:

所以:

cap 就是为了减少“扩容 + 拷贝”的次数。

5. 超过 cap 会发生什么?

当你 append 让 len > cap

你看:又出现“复制旧内容”了对吧?

所以我们才要 尽量提前预留 cap

6. 这时候strings.Builder登场:更“像拼字符串”的工具

你用 []byte 拼字符串没问题,但写起来像在操作数组。 strings.Builder 是 Go 官方提供的:

专门用来高效拼接字符串的工具

你可以把它理解成:

“官方封装好的[]byte + append”

它的用法是:

import "strings"

var b strings.Builder
b.WriteString("blue")
b.WriteByte(' ')
b.WriteString("sky")
result := b.String()

你可以把它理解成:

“内部帮你维护了一个 []byte 的拼接器”

WriteString/WriteByte,它内部就在 append 到那个 buffer 里。

最后 String() 一次性输出。

7. 那Grow又是什么?它和cap的关系是什么?

现在关键来了:

Builder 内部其实也需要容量,否则也会扩容 + 拷贝。

所以它也需要“预留空间”。

这就是:

b.Grow(n)

意思是:

提前保证:接下来还能再写 n 个字节,不用扩容

对应到 slice 的感觉就是:

所以它们关系是:

Grow 本质上是在给 Builder 内部的“隐藏 slice”扩 cap

9. 小白怎么选

你现在阶段记住这个就够了:

简单场景(拼得不多)

+ 也行(比如 2~3 次拼接)

循环里大量拼接(比如这题、构造大字符串)

优先用:

追求性能时加一条:预留容量

到此这篇关于一篇带你看懂Go语言中的字符串拼接(小白入门)的文章就介绍到这了,更多相关Go字符串拼接内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文