【Go】字符串相关问题
点击阅读更多查看文章内容
字符串遍历问题
在使用for i,v:=range str遍历字符串时
str[i]是unit8(byte)类型,返回的是单个字节
字符串在Go中是以字节序列的形式存储的,而 str[i] 直接访问了这个字节序列中的第 i 个字节。如果字符串中的字符是单字节的ASCII字符,那么 s[i] 就足以表示该字符。但是,如果字符是多字节的Unicode字符,那么 s[i] 就只是该字符的第一个字节,而不是整个字符。v是int32(rune)类型,返回的是字符的unicode编码
1 | func main() { |
字符串高效拼接
Go 中,字符串拼接有多种方式,包括 strings.Join
、+
(+=
)、bytes.Buffer
和 strings.Builder
。
方法 | 适用场景 | 性能 | 内存分配次数 | 线程安全 | 备注 |
---|---|---|---|---|---|
strings.Join |
已知字符串切片拼接 | ⭐⭐⭐⭐⭐ | 1 次 | 是 | 最快(预分配内存) |
+ / += |
少量拼接 | ⭐⭐ | 多次 | 是 | 每次拼接都生成新字符串 |
bytes.Buffer |
通用字节/字符串操作 | ⭐⭐⭐ | 1 次 | 是 | 适合混合操作字节和字符串 |
strings.Builder |
高性能字符串拼接 | ⭐⭐⭐⭐ | 1 次 | 否 | 慢于join(零拷贝优化) |
(1) strings.Join
(最快,适用于已知字符串切片)
特点:先预分配内存,后使用strings.Builder拼接
1 | parts := []string{"Hello", "World", "!"} |
适用场景:已有字符串切片,需要拼接成单个字符串。
(2) +
/ +=
(简单但低效)
特点:每次拼接都生成新字符串,导致多次内存分配。
1 | s := "Hello" |
适用场景:少量字符串拼接(如少于 5 次)。
(3) bytes.Buffer
(通用,线程安全)
特点:
- 内存预分配,仅 1 次内存分配
- 线程安全(方法内部加锁)
- 支持混合写入
string
、[]byte
、byte
、rune
。
1 | var buf bytes.Buffer |
适用场景:
需要混合操作字节和字符串。
需要线程安全(但加锁可能影响性能)。
(4) strings.Builder
(最高效,非线程安全)
特点:
- 零拷贝优化(
String()
直接转换底层[]byte
)。 - 最快,比
bytes.Buffer
快约 20%~30%。 - 非线程安全(需自行管理同步)。
示例:
1 | var builder strings.Builder |
适用场景:
- 高频字符串拼接(如循环内拼接)。
- 不需要线程安全(或自行加锁)。