【Go语言学习系列15】标准库探索(二):字符串处理

📚 原创系列: “Go语言学习系列”

🔄 转载说明: 本文最初发布于"Gopher部落"微信公众号,经原作者授权转载。

🔗 关注原创: 欢迎扫描文末二维码,关注"Gopher部落"微信公众号获取第一手Go技术文章。

📑 Go语言学习系列导航

本文是【Go语言学习系列】的第15篇,当前位于第二阶段(基础巩固篇)

🚀 第二阶段:基础巩固篇
  1. 13-包管理深入理解
  2. 14-标准库探索(一):io与文件操作
  3. 15-标准库探索(二):字符串处理 👈 当前位置
  4. 16-标准库探索(三):时间与日期
  5. 17-标准库探索(四):JSON处理
  6. 18-标准库探索(五):HTTP客户端
  7. 19-标准库探索(六):HTTP服务器
  8. 20-单元测试基础
  9. 21-基准测试与性能剖析入门
  10. 22-反射机制基础
  11. 23-Go中的面向对象编程
  12. 24-函数式编程在Go中的应用
  13. 25-context包详解
  14. 26-依赖注入与控制反转
  15. 27-第二阶段项目实战:RESTful API服务

📚 查看完整Go语言学习系列导航

📖 文章导读

在本文中,您将了解:

  • 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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gopher部落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值