锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

Go语言学习笔记—golang标准库bytes包

时间:2022-09-17 11:00:01 kk系列连接器

文章目录

  • 简介
  • 一 相关函数
    • 1.1 转换
    • 1.2 比较
    • 1.3 清理
    • 1.4 拆合
    • 1.5 字串
    • 1.6 替换
    • 1.7 常用函数总结
  • 二 Buffer类型
    • 2.1 声明Buffer的方法
    • 2.2 往Buffer中写入数据
    • 2.3 从Buffer在指定容器中读取数据
    • 2.4 实例演示
    • 2.5 其它相关方法
  • 三 Reader类型


简介

bytes该包提供了一系列读写字节切片的函数。字节切片处理函数多分为基本处理函数、比较函数、后缀检查函数、索引函数、分割函数、大小写处理函数和子切片处理函数。

对于传入 []byte参数(参考类型,函数修改会改变外部变量) 函数不会修改输入的参数,返回值要么是参数的副本,要么是参数的切片。(深度函数可以看到大多数函数创建新的字节切片对象并返回)

一 相关函数

1.1 转换

函数 说明
func ToUpper(s []byte) []byte 将 s 所有字符修改为大写格式返回。
func ToLower(s []byte) []byte 将 s 所有字符修改为小写格式返回
func ToTitle(s []byte) []byte 将 s 所有字符修改为标题格式返回
func ToUpperSpecial(_case unicode.SpecialCase, s []byte) []byte 使用指定的映射表 s 所有字符修改为大写格式返回。
func ToLowerSpecial(_case unicode.SpecialCase, s []byte) []byte 使用指定的映射表 s 将所有字符修改为小写格式返回。
func ToTitleSpecial(_case unicode.SpecialCase, s []byte) []byte 使用指定的映射表 s 中的所有字符修改为标题格式返回。
func Title(s []byte) []byte 将 s 修改所有单词的首字符 Title 格式返回。(缺点:处理不当 Unicode 分隔标点符号的单词。

实例演示:

package main  import (  "bytes"  "fmt" )  func main() { 
          var b = []byte("seafood") //强制类型转换   a := bytes.ToUpper(b)  fmt.Println(a, b)    c := b[0:4]  c[0] = 'A'  fmt.Println(c, b) } 

运行结果:

[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go" [83 69 65 70 79 79 68] [
       
        115 
        101 
        97 
        102 
        111 
        111 
        100
        ] 
        [
        65 
        101 
        97 
        102
        ] 
        [
        65 
        101 
        97 
        102 
        111 
        111 
        100
        ] 
        [Done
        ] exited with code
        =
        0 in 
        1.023 seconds 
       

可以看出函数不会修改原引用值类型。

1.2 比较

函数 说明
func Compare(a, b []byte) int 比较两个 []byte,nil 参数相当于空 []byte。a < b 返回 -1;a == b 返回 0;a > b 返回 1
func Equal(a, b []byte) bool 判断 a、b 是否相等,nil 参数相当于空 []byte。
func EqualFold(s, t []byte) bool 判断 s、t 是否相似,忽略大写、小写、标题三种格式的区别。

实例演示:

package main

import (
	"bytes"
	"fmt"
)

func main() { 
        
	s1 := "Φφϕ kKK"
	s2 := "ϕΦφ KkK"

	// 看看 s1 里面是什么
	for _, c := range s1 { 
        
		fmt.Printf("%-5x", c)
	}
	fmt.Println()
	// 看看 s2 里面是什么
	for _, c := range s2 { 
        
		fmt.Printf("%-5x", c)
	}
	fmt.Println()
	// 看看 s1 和 s2 是否相似
	fmt.Println(bytes.EqualFold([]byte(s1), []byte(s2)))
}

运行结果:

[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
3a6  3c6  3d5  20   6b   4b   212a 
3d5  3a6  3c6  20   212a 6b   4b   
true

[Done] exited with code=0 in 0.978 seconds

1.3 清理

函数 说明
func Trim(s []byte, cutset string) []byte 去掉 s 两边包含在 cutset 中的字符(返回 s 的切片
func TrimLeft(s []byte, cutset string) []byte 去掉 s 左边包含在 cutset 中的字符(返回 s 的切片)
func TrimRight(s []byte, cutset string) []byte 去掉 s 右边包含在 cutset 中的字符(返回 s 的切片)
func TrimFunc(s []byte, f func(r rune) bool) []byte 去掉 s 两边符合 f函数====返回值是true还是false 要求的字符(返回 s 的切片)
func TrimLeftFunc(s []byte, f func(r rune) bool) []byte 去掉 s左边符合 f函数====返回值是true还是false 要求的字符(返回 s 的切片)
func TrimRightFunc(s []byte, f func(r rune) bool) []byte 去掉 s右边符合 f函数====返回值是true还是false 要求的字符(返回 s 的切片)
func TrimSpace(s []byte) []byte 去掉 s 两边的空白(unicode.IsSpace)(返回 s 的切片)
func TrimPrefix(s, prefix []byte) []byte 去掉 s 的前缀 prefix(返回 s 的切片)
func TrimSuffix(s, suffix []byte) []byte 去掉 s 的后缀 suffix(返回 s 的切片)

实例演示:

package main

import (
	"bytes"
	"fmt"
)

func main() { 
        
	bs := [][]byte{ 
         //[][]byte 字节切片 二维数组
		[]byte("Hello World !"),
		[]byte("Hello 世界!"),
		[]byte("hello golang ."),
	}

	f := func(r rune) bool { 
        
		return bytes.ContainsRune([]byte("!!. "), r) //判断r字符是否包含在"!!. "内
	}

	for _, b := range bs { 
         //range bs 取得下标和[]byte
		fmt.Printf("去掉两边: %q\n", bytes.TrimFunc(b, f)) //去掉两边满足函数的字符
	}

	for _, b := range bs { 
        
		fmt.Printf("去掉前缀: %q\n", bytes.TrimPrefix(b, []byte("Hello "))) //去掉前缀
	}
}

运行结果:

[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
去掉两边: "Hello World"
去掉两边: "Hello 世界"
去掉两边: "hello golang"
去掉前缀: "World !"
去掉前缀: "世界!"
去掉前缀: "hello golang ."

[Done] exited with code=0 in 0.925 seconds

1.4 拆合

函数 说明
func Split(s, sep []byte) [][]byte Split 以 sep 为分隔符将 s 切分成多个子串,结果不包含分隔符。如果 sep 为空,则将 s 切分成 Unicode 字符列表。
func SplitN(s, sep []byte, n int) [][]byte SplitN 可以指定切分次数 n,超出 n 的部分将不进行切分。
func SplitAfter(s, sep []byte) [][]byte 功能同 Split,只不过结果包含分隔符(在各个子串尾部)。
func SplitAfterN(s, sep []byte, n int) [][]byte 功能同 SplitN,只不过结果包含分隔符(在各个子串尾部)。
func Fields(s []byte) [][]byte 以连续空白为分隔符将 s 切分成多个子串,结果不包含分隔符。
func FieldsFunc(s []byte, f func(rune) bool) [][]byte 以符合 f 的字符为分隔符将 s 切分成多个子串,结果不包含分隔符。
func Join(s [][]byte, sep []byte) []byte 以 sep 为连接符,将子串列表 s 连接成一个字节串。
func Repeat(b []byte, count int) []bytec 将子串 b 重复 count 次后返回。

实例演示:

package main

import (
	"bytes"
	"fmt"
)

func main() { 
        
	b := []byte(" Hello World ! ")
	fmt.Printf("b: %q\n", b)
	fmt.Printf("%q\n", bytes.Split(b, []byte{ 
        ' '}))

	fmt.Printf("%q\n", bytes.Fields(b))

	f := func(r rune) bool { 
        
		return bytes.ContainsRune([]byte(" !"), r)
	}
	fmt.Printf("%q\n", bytes.FieldsFunc(b, f))
}

运行结果:

[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
b: " Hello World ! "
["" "" "Hello" "" "" "World" "!" "" ""]
["Hello" "World" "!"]
["Hello" "World"]

[Done] exited with code=0 in 1.032 seconds

1.5 字串

函数 说明
func HasPrefix(s, prefix []byte) bool 判断 s 是否有前缀 prefix
func HasSuffix(s, suffix []byte) bool 判断 s 是否有后缀 suffix
func Contains(b, subslice []byte) bool 判断 b 中是否包含子串 subslice
func ContainsRune(b []byte, r rune) bool 判断 b 中是否包含子串 字符 r
func ContainsAny(b []byte, chars string) bool 判断 b 中是否包含 chars 中的任何一个字符
func Index(s, sep []byte) int 查找子串 sep在 s 中第一次出现的位置,找不到则返回 -1
func IndexByte(s []byte, c byte) int 查找子串 字节 c在 s 中第一次出现的位置,找不到则返回 -1
func IndexRune(s []byte, r rune) int 查找子串字符 r在 s 中第一次出现的位置,找不到则返回 -1
func IndexAny(s []byte, chars string) int 查找 chars 中的任何一个字符在 s 中第一次出现的位置,找不到则返回 -1。
func IndexFunc(s []byte, f func(r rune) bool) int 查找符合 f 的字符在 s 中第一次出现的位置,找不到则返回 -1。
func LastIndex(s, sep []byte) int 功能同上,只不过查找最后一次出现的位置。
func LastIndexByte(s []byte, c byte) int 功能同上,只不过查找最后一次出现的位置。
func LastIndexAny(s []byte, chars string) int 功能同上,只不过查找最后一次出现的位置。
func LastIndexFunc(s []byte, f func(r rune) bool) int 功能同上,只不过查找最后一次出现的位置。
func Count(s, sep []byte) int 获取 sep 在 s 中出现的次数(sep 不能重叠)。

实例演示:

package main

import (
	"bytes"
	"fmt"
)

func main() { 
        
	b := []byte("hello golang") //字符串强转为byte切片
	sublice1 := []byte("hello")
	sublice2 := []byte("Hello")
	fmt.Println(bytes.Contains(b, sublice1)) //true
	fmt.Println(bytes.Contains(b, sublice2)) //false

	s := []byte("hellooooooooo")
	sep1 := []byte("h")
	sep2 := []byte("l")
	sep3 := []byte("o")
	fmt.Println(bytes.Count(s, sep1)) //1
	fmt.Println(bytes.Count(s, sep2)) //2
	fmt.Println(bytes.Count(s, sep3)) //9
}

运行结果:

[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
true
false
1
2
9

[Done] exited with code=0 in 1.03 seconds

1.6 替换

函数 说明
func Replace(s, old, new []byte, n int) []byte 将 s 中前 n 个 old 替换为 new,n < 0 则替换全部。
func Map(mapping func(r rune) rune, s []byte) []byte 将 s 中的字符替换为 mapping® 的返回值,如果 mapping 返回负值,则丢弃该字符。
func Runes(s []byte) []rune 将 s 转换为 []rune 类型返回

实例演示:

package main

import (
	"bytes"
	"fmt"
)

func main() { 
        
	s := []byte("hello,world")
	old := []byte("o")
	news := []byte("ee")
	fmt.Println(string(bytes.Replace(s, old, news, 0)))  //hello,world
	fmt.Println(string(bytes.Replace(s, old, news, 1)))  //hellee,world
	fmt.Println(string(bytes.Replace(s, old, news, 2)))  //hellee,weerld
	fmt.Println(string(bytes.Replace(s, old, news, -1))) //hellee,weerld

	s1 := []byte("你好世界")
	r := bytes.Runes(s1)
	fmt.Println("转换前字符串的长度:", len(s1)) //12
	fmt.Println("转换后字符串的长度:", len(r))  //4
}

运行结果:

[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
hello,world
hellee,world
hellee,weerld
hellee,weerld
转换前字符串的长度: 12
转换后字符串的长度: 4

[Done] exited with code=0 in 0.933 seconds

1.7 常用函数总结

常用方法 函数 说明
Contains func Contains(b, subslice []byte) bool 判断 b 中是否包含子串 subslice
Count func Count(s, sep []byte) int 获取 sep 在 s 中出现的次数(sep 不能重叠)。
Repeat func Repeat(b []byte, count int) []bytec 将子串 b 重复 count 次后返回。
Replace func Replace(s, old, new []byte, n int) []byte 将 s 中前 n 个 old 替换为 new,n < 0 则替换全部。
Runes func Runes(s []byte) []rune 将 s 转换为 []rune 类型返回
Join func Join(s [][]byte, sep []byte) []byte 以 sep 为连接符,将子串列表 s 连接成一个字节串。

实例演示:

package main

import (
	"bytes"
	"fmt"
)

func main() { 
        
	//Contains
	b := []byte("hello world") //字符串强转为byte切片
	sublice1 := []byte("hello w")
	sublice2 := []byte("Hello w")
	fmt.Println(bytes.Contains(b, sublice1)) //true
	fmt.Println(bytes.Contains(b, sublice2)) //false

	//Count
	s := []byte("hellooooooooo")
	sep1 := []byte("h")
	sep2 := []byte("l")
	sep3 := []byte("o")
	fmt.Println(bytes.Count(s, sep1)) //1
	fmt.Println(bytes.Count(s, sep2)) //2
	fmt.Println(bytes.Count(s, sep3)) //9

	//Repeat
	b = []byte("hi")
	fmt.Println(string(bytes.Repeat(b, 1))) //hi
	fmt.Println(string(bytes.Repeat(b, 3))) //hihihi

	//Replace
	s = []byte("hello,world")
	old := []byte("o")
	news := []byte("ee")
	fmt.Println(string(bytes.Replace(s, old, news, 0)))  //hello,world
	fmt.Println(string(bytes.Replace(s, old, news, 1)))  //hellee,world
	fmt.Println(string(bytes.Replace(s, old, news, 2)))  //hellee,weerld
	fmt.Println(string(bytes.Replace(s, old, news, -1))) //hellee,weerld

	//Runes
	s = []byte("你好世界")
	r := bytes.Runes(s)
	fmt.Println("转换前字符串的长度:", len(s)) //12
	fmt.Println("转换后字符串的长度:", len(r)) //4

	//Join
	s2 := [][]byte{ 
        []byte("你好"), []byte("世界")}
	sep4 := []byte(",")
	fmt.Println(string(bytes.Join(s2, sep4))) //你好,世界
	sep5 := []byte("#")
	fmt.Println(string(bytes.Join(s2, sep5))) //你好#世界

}

运行结果:

[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
true
false
1
2
9
hi
hihihi
hello,world
hellee,world
hellee,weerld
hellee,weerld
转换前字符串的长度: 12
转换后字符串的长度: 4
你好,世界
你好#世界

[Done] exited with code=0 in 1.146 seconds

二 Buffer类型

缓冲区是具有读取和写入方法的可变大小的字节缓冲区。Buffer的零值是准备使用的空缓冲区。

type Buffer struct { 
        
  	buf       []byte   // contents are the bytes buf[off : len(buf)]
  	off       int      // read at &buf[off], write at &buf[len(buf)]
  	bootstrap [64]byte // memory to hold first slice; helps small buffers avoid allocation.
  	lastRead  readOp   // last read operation, so that Unread* can work correctly.
  
  	// FIXME: it would be advisable to align Buffer to cachelines to avoid false
  	// sharing.
}

2.1 声明Buffer的方法

方法 说明
var b bytes.Buffer 直接定义一个Buffer变量,不用初始化,可以直接使用
b := new(bytes.Buffer) 使用New返回Buffer变量
b := bytes.NewBuffer(s []byte) 从一个[]byte切片,构造一个Buffer
b := bytes.NewBufferString(s string) 从一个string变量,构造一个Buffer

2.2 往Buffer中写入数据

方法 说明
b.Write(d []byte) 将切片d写入Buffer数据
b.WriteString(s string) 将字符串s写入Buffer尾部
b.WriteByte(c byte) 将字符c写入Buffer尾部
b.WriteRune(r rune) 将一个rune类型的数据放到缓冲器的尾部
b.WriteTo(w io.Writer) 将Buffer中的内容输出到实现了io.Writer接口的可写入对象中

2.3 从Buffer中读取数据到指定容器

c := make([]byte, 8)
方法 说明
b.Read(c) 一次读取8个byte到c容器中,每次读取新的8个byte覆盖c中原来的内容
b.ReadByte() 读取第一个byte,b的第一个byte被拿掉,赋值给 a => a, _ := b.ReadByte()
b.ReadRune() 读取第一个rune,b的第一个rune被拿掉,赋值给 r => r, _ := b.ReadRune()
b.ReadBytes(delimiter byte) 需要一个byte作为分隔符,读的时候从缓冲器里找第一个出现的分隔符(delim),找到后,把从缓冲器头部开始到分隔符之间的所有byte进行返回,作为byte类型的slice,返回后,缓冲器也会空掉一部分
b.ReadString(delimiter byte) 需要一个byte作为分隔符,读的时候从缓冲器里找第一个出现的分隔符(delim),找到后,把从缓冲器头部开始到分隔符之间的所有byte进行返回,作为字符串返回,返回后,缓冲器也会空掉一部分
b.ReadFrom(i io.Reader) 从一个实现io.Reader接口的r,把r里的内容读到缓冲器里,n返回读的数量

2.4 实例演示

package main

import (
	"bytes"
	"fmt"
)

func main() { 
        
	rd := bytes.NewBufferString("Hello World!")
	buf := make([]byte, 

相关文章