Go语言中strings库提供字符串处理函数,如Contains、ReplaceAll、Split、Trim等,用于判断、替换、分割和清理字符串;其与bytes库主要区别在于string不可变而[]byte可变,strings适用于文本操作,bytes适用于二进制或高频拼接;处理Unicode时需注意字节与rune差异,避免切片错误;高频拼接应优先使用strings.Builder或bytes.Buffer以提升性能。

在Go语言中,
strings
strings
首先是判断与查找。比如你想知道一个字符串里是不是包含了某个子串,或者以某个前缀、后缀开头或结尾。
strings.Contains(s, substr)
strings.Index(s, substr)
strings.LastIndex(s, substr)
package main
import (
"fmt"
"strings"
)
func main() {
text := "Hello, Go programming language!"
// 判断是否包含
fmt.Println("Contains 'Go':", strings.Contains(text, "Go")) // true
fmt.Println("HasPrefix 'Hello':", strings.HasPrefix(text, "Hello")) // true
fmt.Println("HasSuffix 'language!':", strings.HasSuffix(text, "language!")) // true
// 查找位置
fmt.Println("Index of 'Go':", strings.Index(text, "Go")) // 7
fmt.Println("LastIndex of 'a':", strings.LastIndex(text, "a")) // 23 (language)
}接着是替换与修改。有时候,我们需要把字符串中的某些部分换掉。
strings.ReplaceAll(s, old, new)
old
new
strings.Replace(s, old, new, n)
n
strings.ToUpper(s)
strings.ToLower(s)
立即学习“go语言免费学习笔记(深入)”;
package main
import (
"fmt"
"strings"
)
func main() {
sentence := "Go is awesome, Go is fun!"
// 替换所有
newSentence := strings.ReplaceAll(sentence, "Go", "Golang")
fmt.Println("ReplaceAll:", newSentence) // Golang is awesome, Golang is fun!
// 替换前n个
partialReplace := strings.Replace(sentence, "Go", "Python", 1)
fmt.Println("Replace (1st only):", partialReplace) // Python is awesome, Go is fun!
// 大小写转换
fmt.Println("ToUpper:", strings.ToUpper(sentence)) // GO IS AWESOME, GO IS FUN!
fmt.Println("ToLower:", strings.ToLower(sentence)) // go is awesome, go is fun!
}再来是分割与拼接。当我们需要将一个长字符串按照某个分隔符拆分成多个小块,或者将多个小块重新组合起来时,
strings.Split(s, sep)
strings.Join(elems, sep)
Split
Join
package main
import (
"fmt"
"strings"
)
func main() {
csvData := "apple,banana,cherry"
parts := strings.Split(csvData, ",")
fmt.Println("Split:", parts) // [apple banana cherry]
words := []string{"hello", "world", "golang"}
joined := strings.Join(words, "-")
fmt.Println("Join:", joined) // hello-world-golang
}最后是清理与修剪。处理用户输入或者从文件读取的数据时,常常会遇到多余的空格、换行符或者特定的前缀后缀。
strings.TrimSpace(s)
strings.TrimPrefix(s, prefix)
strings.TrimSuffix(s, suffix)
strings.Trim(s, cutset)
cutset
package main
import (
"fmt"
"strings"
)
func main() {
dirtyString := " \t Hello Go! \n "
trimmed := strings.TrimSpace(dirtyString)
fmt.Println("TrimSpace:", trimmed) // Hello Go!
filePath := "/usr/local/bin/go"
noPrefix := strings.TrimPrefix(filePath, "/usr/local")
fmt.Println("TrimPrefix:", noPrefix) // /bin/go
fileName := "document.txt"
noSuffix := strings.TrimSuffix(fileName, ".txt")
fmt.Println("TrimSuffix:", noSuffix) // document
customTrim := strings.Trim("---hello---", "-")
fmt.Println("Trim custom:", customTrim) // hello
}这些只是
strings
strings
bytes
在我看来,
strings
bytes
核心区别在于:
string
[]byte
strings
strings.ReplaceAll
string
bytes
strings
[]byte
bytes.ReplaceAll
[]byte
bytes.Buffer
bytes
何时选用:
选用strings
strings
选用bytes
bytes.Buffer
bytes
举个例子,如果我只是想检查一个URL路径是否包含某个特定参数,我会用
strings.Contains
bytes.Buffer
strings
Go语言的字符串是UTF-8编码的字节序列,而不是Unicode码点序列。这意味着,一个字符(rune)可能由一个或多个字节组成。这一点在处理非ASCII字符,特别是中文、日文等时,显得尤为重要,也常常是新手容易踩坑的地方。
strings
len(s)
s
len(s)
s := "你好Go" // "你"占3字节,"好"占3字节,"G"占1字节,"o"占1字节 fmt.Println(len(s)) // 输出 8,而不是 4
如果你需要获取Unicode字符的数量,应该使用
utf8.RuneCountInString(s)
[]rune
import "unicode/utf8" fmt.Println(utf8.RuneCountInString(s)) // 输出 4 fmt.Println(len([]rune(s))) // 输出 4
strings.Index(s, substr)
strings.LastIndex(s, substr)
s := "你好世界" substr := "世界" fmt.Println(strings.Index(s, substr)) // 输出 6。因为"你"3字节,"好"3字节,所以"世界"从第6个字节开始
如果你的查找逻辑需要基于Unicode码点(rune)的索引,你可能需要先将字符串转换为
[]rune
strings.IndexRune
字符串切片操作 s[start:end]
start
end
s := "你好Go" // 错误示例:试图切分多字节字符的中间 // fmt.Println(s[0:1]) // 可能会得到乱码或无效UTF-8 fmt.Println(s[0:3]) // "你" fmt.Println(s[6:8]) // "Go"
要正确地按字符切片,应该先转换为
[]rune
string
runes := []rune(s) fmt.Println(string(runes[0:2])) // "你好"
strings.Repeat(s, count)
strings.TrimPrefix/Suffix/Space
总的来说,当处理包含Unicode字符的字符串时,如果你的操作是基于“字符”的逻辑(例如,我想获取字符串的第N个字符,或者我想从第M个字符开始切片),那么你需要时刻记住Go字符串的字节本质,并考虑使用
[]rune
utf8
strings.IndexRune
strings
频繁的字符串拼接在Go中是一个常见的性能陷阱,尤其是在循环中或者处理大量数据时。Go的
string
+
在实际项目中,优化字符串拼接通常有几种策略,按推荐度从低到高排列:
避免在循环中直接使用+
var result string
for _, item := range items {
result += item.Name + "," // 每次循环都会创建新字符串
}这几乎肯定会成为性能瓶颈。
使用fmt.Sprintf
fmt.Sprintf
name := "Alice"
age := 30
message := fmt.Sprintf("User: %s, Age: %d", name, age)虽然比直接
+
使用strings.Join
[]string
strings.Join
parts := []string{"hello", "world", "golang"}
result := strings.Join(parts, " ") // 推荐这是处理已知字符串列表拼接的最佳方式。
使用strings.Builder
strings.Builder
WriteString
WriteByte
String()
package main
import (
"fmt"
"strings"
"time"
)
func main() {
// 模拟一个需要频繁拼接的场景
const numIterations = 10000
// 方式1: 使用 + 运算符 (性能差)
start := time.Now()
var sPlus string
for i := 0; i < numIterations; i++ {
sPlus += "a"
}
fmt.Printf("Using '+' operator: %s (len: %d)\n", time.Since(start), len(sPlus))
// 方式2: 使用 strings.Builder (性能优异)
start = time.Now()
var sb strings.Builder
// 预分配内存,如果知道大概的最终长度,可以进一步优化
sb.Grow(numIterations) // 可选,但推荐
for i := 0; i < numIterations; i++ {
sb.WriteString("a")
}
sBuilder := sb.String()
fmt.Printf("Using strings.Builder: %s (len: %d)\n", time.Since(start), len(sBuilder))
// 方式3: 使用 []byte 和 bytes.Buffer (同样高效,适合字节操作)
// 虽然标题是strings库,但bytes.Buffer是等效的优化手段,
// 尤其当内容源是[]byte时更自然
// import "bytes"
// var bb bytes.Buffer
// bb.Grow(numIterations)
// for i := 0; i < numIterations; i++ {
// bb.WriteByte('a') // 或 bb.WriteString("a")
// }
// sBuffer := bb.String()
// fmt.Printf("Using bytes.Buffer: %s (len: %d)\n", time.Since(start), len(sBuffer))
}在我的机器上运行,
strings.Builder
+
strings.Builder
使用bytes.Buffer
[]byte
bytes.Buffer
strings.Builder
[]byte
bytes.Buffer
package main
import (
"bytes"
"fmt"
)
func main() {
var b bytes.Buffer
b.WriteString("Hello, ")
b.Write([]byte("World!")) // 可以直接写入字节切片
b.WriteByte(' ')
b.WriteString("GoLang.")
fmt.Println(b.String()) // Hello, World! GoLang.
}在性能上,
bytes.Buffer
strings.Builder
string
[]byte
在实际项目中,我个人经验是,只要涉及到循环中的字符串拼接,或者构建大型字符串(如日志消息、JSON响应体、HTML内容等),我几乎总是会首先考虑
strings.Builder
bytes.Buffer
以上就是Golang strings库常用字符串操作方法的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号