📚 原创系列: “Go语言学习系列”
🔄 转载说明: 本文最初发布于"Gopher部落"微信公众号,经原作者授权转载。
🔗 关注原创: 欢迎扫描文末二维码,关注"Gopher部落"微信公众号获取第一手Go技术文章。
📑 Go语言学习系列导航
🚀 第二阶段:基础巩固篇本文是【Go语言学习系列】的第15篇,当前位于第二阶段(基础巩固篇)
- 13-包管理深入理解
- 14-标准库探索(一):io与文件操作
- 15-标准库探索(二):字符串处理 👈 当前位置
- 16-标准库探索(三):时间与日期
- 17-标准库探索(四):JSON处理
- 18-标准库探索(五):HTTP客户端
- 19-标准库探索(六):HTTP服务器
- 20-单元测试基础
- 21-基准测试与性能剖析入门
- 22-反射机制基础
- 23-Go中的面向对象编程
- 24-函数式编程在Go中的应用
- 25-context包详解
- 26-依赖注入与控制反转
- 27-第二阶段项目实战:RESTful API服务
📖 文章导读
在本文中,您将了解:
- Go语言字符串的基本概念与内部表示
- strings包提供的常用字符串操作函数
- strconv包在字符串与其他类型转换中的应用
- unicode/utf8包在处理Unicode文本中的作用
- 高效字符串处理的最佳实践与常见陷阱
字符串处理是几乎所有编程任务中不可或缺的一部分,掌握Go语言强大的字符串处理能力,能够极大提升您的开发效率和代码质量。
标准库探索(二):字符串处理
1. Go中的字符串基础
在Go语言中,字符串是不可变的字节序列,使用UTF-8编码。这种设计选择使Go能够高效处理多语言文本,特别是在国际化应用中。让我们从基础概念开始,了解Go中的字符串特性。
1.1 字符串的本质
在Go中,字符串是一个只读的字节序列:
s := "Hello, 世界"
fmt.Println(len(s)) // 输出13,而不是9个字符
为什么长度是13而不是9?因为UTF-8是变长编码:
- ASCII字符(如英文字母)占1个字节
- 中文字符通常占3个字节
1.2 字符与符文(Rune)
在Go中,rune类型表示一个Unicode码点(code point),对应一个字符:
// 遍历字符串中的Unicode字符
for i, r := range "Hello, 世界" {
fmt.Printf("%d: %c [%d]\n", i, r, r)
}
输出:
0: H [72]
1: e [101]
2: l [108]
3: l [108]
4: o [111]
5: , [44]
6: [32]
7: 世 [19990]
10: 界 [30028]
注意索引是按字节跳跃的,这是因为中文字符占3个字节。
1.3 字符串不可变性
Go中的字符串是不可变的,这意味着一旦创建就不能修改:
s := "hello"
// s[0] = 'H' // 这会导致编译错误
// 要修改字符串,必须创建一个新的
s = "H" + s[1:]
fmt.Println(s) // 输出"Hello"
这种不可变性有几个好处:
- 安全性:字符串可以安全地在多个goroutine间共享
- 可预测的内存使用
- 更好的缓存行为
2. strings包:字符串操作利器
Go的strings包提供了丰富的字符串处理函数,让常见任务变得简单高效。
2.1 搜索函数
查找字符串中的子串或字符:
import "strings"
s := "Go is an open source programming language"
// 检查是否包含子串
fmt.Println(strings.Contains(s, "open")) // true
fmt.Println(strings.ContainsAny(s, "abcd")) // true (包含'a'和'c')
fmt.Println(strings.ContainsRune(s, 'G')) // true
// 查找子串位置
fmt.Println(strings.Index(s, "programming")) // 20
fmt.Println(strings.LastIndex(s, "an")) // 14
fmt.Println(strings.IndexAny(s, "zxq")) // -1 (未找到)
// 检查前缀和后缀
fmt.Println(strings.HasPrefix(s, "Go")) // true
fmt.Println(strings.HasSuffix(s, "language")) // true
2.2 修改函数
创建修改后的字符串副本:
s := " Go programming "
// 大小写转换
fmt.Println(strings.ToUpper(s)) // " GO PROGRAMMING "
fmt.Println(strings.ToLower(s)) // " go programming "
fmt.Println(strings.Title(s)) // " Go Programming " (已弃用)
fmt.Println(cases.Title(language.Und).String(s)) // 新的Title实现
// 移除空白
fmt.Println(strings.TrimSpace(s)) // "Go programming"
fmt.Println(strings.Trim(s, " ")) // "Go programming"
fmt.Println(strings.TrimLeft(s, " ")) // "Go programming "
fmt.Println(strings.TrimRight(s, " ")) // " Go programming"
// 替换
fmt.Println(strings.Replace(s, "Go", "Golang", 1)) // " Golang programming "
fmt.Println(strings.ReplaceAll(s, " ", "_")) // "__Go_programming__"
注意:从Go 1.18开始,strings.Title已被弃用,建议使用golang.org/x/text/cases包中的实现。
2.3 分割与连接
处理字符串列表:
s := "apple,banana,orange,grape"
// 分割字符串
parts := strings.Split(s, ",")
fmt.Println(parts) // [apple banana orange grape]
fmt.Println(strings.SplitN(s, ",", 2)) // [apple banana,orange,grape]
// 按空白字符分割
words := "Go is awesome"
fmt.Println(strings.Fields(words)

最低0.47元/天 解锁文章
585

被折叠的 条评论
为什么被折叠?



