## 使用bytes和strings包
bytes 和 string 包有许多有用的函数以帮助使用者在字符串和字节类型之间进行处理和转换。这些函数可用于创建多种通用 I/O 接口的缓冲区。
### 准备
请参阅上一节,关于使用常见I/O接口的准备步骤。
### 实践
1. 创建buffer.go:
```
package bytestrings
import (
"bytes"
"io"
"io/ioutil"
)
// Buffer 演示了初始化字节缓冲区的一些技巧
// 实现了 io.Reader 接口
func Buffer(rawString string) *bytes.Buffer {
// 将传入的字符串转换为字节数组
rawBytes := []byte(rawString)
// 有很多方式使用字节数组或原始字符串建立缓冲区
var b = new(bytes.Buffer)
b.Write(rawBytes)
// 或者
b = bytes.NewBuffer(rawBytes)
// 使用字符串建立字节数组
b = bytes.NewBufferString(rawString)
return b
}
// ToString接收 io.Reader 并将其转换为字符串返回
func toString(r io.Reader) (string, error) {
b, err := ioutil.ReadAll(r)
if err != nil {
return "", err
}
return string(b), nil
}
```
2. 建立bytes.go,[Golang学习 - bufio 包](https://www.cnblogs.com/golove/p/3282667.html)对buffio解读很完整,值得一读:
```
package bytestrings
import (
"bufio"
"bytes"
"fmt"
)
// WorkWithBuffer 会使用创建自 Buffer 函数的字节缓冲区
func WorkWithBuffer() error {
rawString := "it's easy to encode unicode into a byte array ❤️"
b := Buffer(rawString)
// 使用b.Bytes()可以快速从字节缓冲区获取字节切片
// 使用b.String()可以快速从字节缓冲区获取字符串
fmt.Println(b.String())
// 由于*bytes.Buffer类型的b实现了io Reader 我们可以使用常见的reader函数
s, err := toString(b)
if err != nil {
return err
}
fmt.Println(s)
// 可以创建一个 bytes reader 它实现了
// io.Reader, io.ReaderAt,
// io.WriterTo, io.Seeker, io.ByteScanner, and io.RuneScanner
// 接口
reader := bytes.NewReader([]byte(rawString))
// 我们可以使用其创建 scanner 以允许使用缓存读取和建立 token
scanner := bufio.NewScanner(reader)
scanner.Split(bufio.ScanWords)
// 遍历所有的扫描token
for scanner.Scan() {
fmt.Print(scanner.Text())
}
return nil
}
```
3. 建立 string.go:
```
package bytestrings
import (
"fmt"
"io"
"os"
"strings"
)
// SearchString 展示了一系列在字符串中进行查询的方法
func SearchString() {
s := "this is a test"
// 返回 true 表明包含子串
fmt.Println(strings.Contains(s, "this"))
// 返回 true 表明包含子串中的任何一字符a或b或c
fmt.Println(strings.ContainsAny(s, "abc"))
// 返回 true 表明以该子串开头
fmt.Println(strings.HasPrefix(s, "this"))
// 返回 true 表明以该子串结尾
fmt.Println(strings.HasSuffix(s, "test"))
}
// ModifyString 展示了一系列修改字符串的方法
func ModifyString() {
s := "simple string"
// 输出 [simple string]
fmt.Println(strings.Split(s, " "))
// 输出 "Simple String"
fmt.Println(strings.Title(s))
// 输出 "simple string" 会移除头部和尾部的空白
s = " simple string "
fmt.Println(strings.TrimSpace(s))
}
// StringReader 演示了如何快速创建一个字符串的io.Reader接口
func StringReader() {
s := "simple string\n"
r := strings.NewReader(s)
// 在标准输出上打印 s
io.Copy(os.Stdout, r)
}
```
4. 建立main.go:
```
package main
import "github.com/agtorre/go-cookbook/chapter1/bytestrings"
func main() {
err := bytestrings.WorkWithBuffer()
if err != nil {
panic(err)
}
// each of these print to stdout
bytestrings.SearchString()
bytestrings.ModifyString()
bytestrings.StringReader()
}
```
5. 执行 go run main.go
6. 这会输出(*<small>原文此处将心形显示为乱码,不过在译者的win7 Go1.10.1环境下可以完整显示出来</small>*):
```
it's easy to encode unicode into a byte array ❤️
it's easy to encode unicode into a byte array ❤️
it'seasytoencodeunicodeintoabytearray❤️true
true
true
true
[simple string]
Simple String
simple string
simple string
```
### 说明
bytes 包在处理数据时提供了许多便利功能。 例如,使用流处理库或方法时,缓冲区比字节数组更灵活。一旦你创建了一个缓冲区,它可以用来满足io.Reader接口,所以你可以利用ioutil包中的各种函数来操作数据。 对于流应用,你可能需要使用buffer 和 scanner,bufio包可以在这些情况下派上用场。 有时,使用数组或切片更适合较小的数据集,或者当你的计算机上有大量内存,无需考虑过多考虑时。
Go为这些基本类型的接口之间的转换提供了很大的灵活性——在字符串和字节之间转换相对简单。使用字符串时,string包提供了许多方便的函数来搜索和处理字符串。在某些情况下,一个好的正则表达式可能是合适的,但大多数情况下,string和strconv包就足够了。string包允许你将字符串标题化,将其拆分为数组或修剪空白,它还提供了一个可以用来代替bytes包读取器类型的Reader接口。
* * * *
学识浅薄,错误在所难免。欢迎在群中就本书提出修改意见,以飨后来者,长风拜谢。
Golang中国(211938256)
beego实战(258969317)
Go实践(386056972)
- 前言
- 第一章 I/O和文件系统
- 常见 I/O 接口
- 使用bytes和strings包
- 操作文件夹和文件
- 使用CSV格式化数据
- 操作临时文件
- 使用 text/template和HTML/templates包
- 第二章 命令行工具
- 解析命令行flag标识
- 解析命令行参数
- 读取和设置环境变量
- 操作TOML,YAML和JSON配置文件
- 操做Unix系统下的pipe管道
- 处理信号量
- ANSI命令行着色
- 第三章 数据类型转换和解析
- 数据类型和接口转换
- 使用math包和math/big包处理数字类型
- 货币转换和float64注意事项
- 使用指针和SQL Null类型进行编码和解码
- 对Go数据编码和解码
- Go中的结构体标签和反射
- 通过闭包实现集合操作
- 第四章 错误处理
- 错误接口
- 使用第三方errors包
- 使用log包记录错误
- 结构化日志记录
- 使用context包进行日志记录
- 使用包级全局变量
- 处理恐慌
- 第五章 数据存储
- 使用database/sql包操作MySQL
- 执行数据库事务接口
- SQL的连接池速率限制和超时
- 操作Redis
- 操作MongoDB
- 创建存储接口以实现数据可移植性
- 第六章 Web客户端和APIs
- 使用http.Client
- 调用REST API
- 并发操作客户端请求
- 使用OAuth2
- 实现OAuth2令牌存储接口
- 封装http请求客户端
- 理解GRPC的使用
- 第七章 网络服务
- 处理Web请求
- 使用闭包进行状态处理
- 请求参数验证
- 内容渲染
- 使用中间件
- 构建反向代理
- 将GRPC导出为JSON API
- 第八章 测试
- 使用标准库进行模拟
- 使用Mockgen包
- 使用表驱动测试
- 使用第三方测试工具
- 模糊测试
- 行为驱动测试
- 第九章 并发和并行
- 第十章 分布式系统
- 第十一章 响应式编程和数据流
- 第十二章 无服务器编程
- 第十三章 性能改进