bytes包是go提供的用来操作byte切片的工具包,包含对byte切片的查询,截取,替换,拼接,读取等方法,本章主要介绍查询,截取,替换,拼接等方法; 读取由于涉及buffer缓冲将在第二节讲解。本节内容全是介绍bytes包的各种各样的方法,内容比较单一,没有太多go编程理论知识。
// func Compare(a, b []byte) int
// 比较a,b两个切片是否相等, a=b 返回0,ab 返回1
fmt.Println(bytes.Compare([]byte{},[]byte{})) // 0
fmt.Println(bytes.Compare([]byte{1},[]byte{2})) // -1
fmt.Println(bytes.Compare([]byte{2},[]byte{1})) // 1
fmt.Println(bytes.Compare([]byte{},nil)) // 0
// func Equal(a, b []byte) bool
// 判断两个切片是否完全相同
fmt.Println(bytes.Equal([]byte{},[]byte{})) // true
fmt.Println(bytes.Equal([]byte{'A'},[]byte{'a'})) // false
fmt.Println(bytes.Equal([]byte{},nil)) // true
// func HasPrefix(s, prefix []byte) bool
// 判断s是否有前缀切片prefix
fmt.Println(bytes.HasPrefix([]byte{1,2,3},[]byte{1})) // true
fmt.Println(bytes.HasPrefix([]byte{1,2,3},[]byte{2})) // false
// func HasSuffix(s, suffix []byte) bool
// 判断s是否有后缀切片suffix,与HasPrefix类似不在演示
// func Contains(b, subslice []byte) bool
// 判断切片b是否包含子切片subslice
fmt.Println(bytes.Contains([]byte{1,2,3},[]byte{1})) // true
fmt.Println(bytes.Contains([]byte{1,2,3},[]byte{1,3})) // false
// func Index(s, sep []byte) int
// 子切片sep在s中第一次出现的位置,不存在则返回-1
fmt.Println(bytes.Index([]byte{1,2,3,4,5},[]byte{2,3})) // 1
fmt.Println(bytes.Index([]byte{1,2,3,4,5},[]byte{0,1})) // -1
// func IndexByte(s []byte, c byte) int
// 字符c在s中第一次出现的位置,不存在则返回-1
fmt.Println(bytes.IndexByte([]byte{1,2,3},2)) // 1
fmt.Println(bytes.IndexByte([]byte{1,2,3},0)) // -1
// func IndexFunc(s []byte, f func(r rune) bool) int
// s中第一个满足函数f的元素的索引,不存在则返回-1
fmt.Println(bytes.IndexFunc([]byte("hi go"), func(r rune) bool {
return r == 'g'
})) // 3 ; hi go中g的索引为3
// func LastIndexFunc(s []byte, f func(r rune) bool) int
// 这个方法与IndexFunc相反,获取最后一个满足函数f的元素的索引,不再演示
// func LastIndex(s, sep []byte) int
// 切片sep在s中最后一次出现的位置,不存在则返回-1
fmt.Println(bytes.LastIndex([]byte("hi go"),[]byte("go"))) // 3
fmt.Println(bytes.LastIndex([]byte{1,2,3},[]byte{2,3})) // 1
// func ToLower(s []byte) []byte
// 返回将s切片所有字符都转为小写的新切片(下面将切片转为字符串方便看到结果)
fmt.Println(string(bytes.ToLower([]byte("ABC")))) // abc
fmt.Println(string(bytes.ToLower([]byte("abc")))) // abc
// func ToUpper(s []byte) []byte
// 这个方法将s切片字符全部转为大写,与ToLower相反,不再演示
// func Repeat(b []byte, count int) []byte
// 返回count个b切片串联起来的新切片
fmt.Println(bytes.Repeat([]byte{1,2},3)) // [1 2 1 2 1 2]
// func Replace(s, old, new []byte, n int) []byte
// 将s中n个old切片替换new切片,并返回这个新切片,当n为-1时,表示替换所有
fmt.Println(bytes.Replace([]byte{1,1,3,1,1,3,1,1,4},[]byte{1,1},[]byte{0,0},-1)) // [0 0 3 0 0 3 0 0 4]
// func ReplaceAll(s, old, new []byte) []byte
// ReplaceAll这个函数表示替换所有,与Replace中n为-1时效果是一样的
// func Map(mapping func(r rune) rune, s []byte) []byte
// 将s切片的每一个字符元素都进行mapping函数运算,并将得到的结果拼接成新切片返回
fmt.Println(string(bytes.Map(func(r rune) rune {
return r + 1 // 将每一个字符都+1
},[]byte("abc")))) // bcd
// func Trim(s []byte, cutset string) []byte
// 返回将s前后端所有cutset值都去掉的子切片
fmt.Println(string(bytes.Trim([]byte("hi go hi js"),"hi"))) // go hi js ; 只去除收尾hi,不会去除中间hi
// func TrimSpace(s []byte) []byte
// 将前后端所有的空白都去除,并返回新的切片
fmt.Println(bytes.TrimSpace([]byte(" hi go "))) // [104 105 32 103 111]; 只有五个字符,可以看到,去除了首尾的空字符
// func TrimLeft(s []byte, cutset string) []byte
// 返回将s左边等于cutset的值去掉的新切片
fmt.Println(string(bytes.TrimLeft([]byte("hihi go"), "hi"))) // go
// func TrimRight(s []byte, cutset string) []byte
// 返回将s右边等于cutset的值去掉的新切片,与TrimLeft类似不再演示
// func TrimPrefix(s, prefix []byte) []byte
// 返回将s去除prefix前缀的新切片
fmt.Println(string(bytes.TrimPrefix([]byte("hi go"),[]byte("hi")))) // go
// 返回将s去除suffix后缀的新切片,不再演示
// func TrimSuffix(s, suffix []byte) []byte
fmt.Println(string(bytes.TrimSuffix([]byte("hi go"),[]byte("go")))) // hi
// func Fields(s []byte) [][]byte
// 返回将s安装空字符切割的多个子切片
s := bytes.Fields([]byte(" hi go, hi js, hi c"))
for _,v := range s {
fmt.Println(string(v))// 依次打印 hi|go,|hi|js,|hi|c
}
// func FieldsFunc(s []byte, f func(rune) bool) [][]byte
// 与Fields类似,但是FieldsFunc是以满足函数f条件的字符为分隔符
s = bytes.FieldsFunc([]byte(" hi go, hi.js-hi c"),func(r rune) bool {
return r == ','||r == '-'||r == '.' // 只要是,-. 都可以作为分隔符
})
for _,v := range s {
fmt.Println(string(v))// 依次打印 hi go| hi|js,|hi c
}
// func Split(s, sep []byte) [][]byte
// 以sep作为分隔符进行分割
s = bytes.Split([]byte(" hihi go hi js hihi c"),[]byte("hi"))
for _,v := range s {
fmt.Println(string(v))// 依次打印 | | go| js| | c 注意中间的空格
}
// func SplitN(s, sep []byte, n int) [][]byte
// 以sep作为分隔符进行分割,n为分割的个数;不再演示
// n > 0 : 返回的切片最多n个子字符串;最后一个子字符串包含未进行切割的部分。
// n == 0: 返回nil
// n < 0 : 返回所有的子字符串组成的切片
// func Join(s [][]byte, sep []byte) []byte
// 将所有的[][]byte连接成一个新切片,以sep作为连接符号
fmt.Println(bytes.Join([][]byte{{1,1},{2,2},{3,3}},[]byte{0})) // [1 1 0 2 2 0 3 3]
// func EqualFold(s, t []byte) bool
// 判断两个utf-8编码切片(将unicode大写、小写、标题三种格式字符视为相同)是否相同。跟Equal方法差不多,只不过比较的编码不一样
fmt.Println(bytes.EqualFold([]byte{},[]byte{})) // true
fmt.Println(bytes.EqualFold([]byte{'A'},[]byte{'a'})) // true ;大小写视为相同,这里跟Equal方法不同
fmt.Println(bytes.EqualFold([]byte{},nil)) // true
// func Runes(s []byte) []rune
// 返回和s等价的[]rune切片。(将utf-8编码的unicode码值分别写入单个rune)
// 不了解rune类型的朋友看下面的例子就清楚了
// 先看看rune切片的内容
fmt.Println([]byte("I 你")) // [73 32 228 189 160]
fmt.Println(bytes.Runes([]byte("I 你"))) // [73 32 20320] 这里就可以清楚的看到区别了
// 再看看长度
fmt.Println(len([]byte("I 你"))) // 5, 打印5是因为‘你‘这个中文汉子在utf8编码中占3个字节,而go的默认编码就是utf8
fmt.Println(len(bytes.Runes([]byte("I 你")))) // 3 ,打印3是因为,将utf8的三个字节写入到了一个rune
// func Count(s, sep []byte) int
// 计算s中有多少个不重叠的sep子切片
fmt.Println(bytes.Count([]byte{1,2,3,5,1,2,5,4},[]byte{1,2})) // 2 ,在s里面 1,2出现了2次
fmt.Println(bytes.Count([]byte{1,2,3,5,1,2,5,4},[]byte{1,1})) // 0
// func IndexRune(s []byte, r rune) int
// unicode字符r的utf-8编码在s中第一次出现的位置,不存在则返回-1
fmt.Println(bytes.IndexRune([]byte("hi 你"),rune('你'))) // 3
fmt.Println(bytes.IndexRune([]byte("hi 你"),rune('h'))) // 0
// func IndexAny(s []byte, chars string) int
// 字符串chars中的任一utf-8编码在s中第一次出现的位置,如不存在或者chars为空字符串则返回-1
fmt.Println(bytes.IndexAny([]byte("hello"),"e")) // 1
fmt.Println(bytes.IndexAny([]byte("hello"),"ea")) // 1
fmt.Println(bytes.IndexAny([]byte("hello"),"ae")) // 1
fmt.Println(bytes.IndexAny([]byte("hello"),"c")) // -1
// func LastIndexAny(s []byte, chars string) int
// 这个方法与IndexAny相反,获取chars任意字符在是中最后一次出现的位置,不再演示
// func Title(s []byte) []byte
// 返回s中第一个字符改为大写的切片(下面将切片转为字符串方便看到结果)
fmt.Println(string(bytes.Title([]byte("AAA")))) // AAA
fmt.Println(string(bytes.Title([]byte("aaa")))) // Aaa
// func ToTitle(s []byte) []byte
// 与ToUpper类似,都将所有字符转为大写
fmt.Println(string(bytes.ToTitle([]byte("Aaa")))) // AAA
fmt.Println(string(bytes.ToUpper([]byte("Aaa")))) // AAA
// func TrimFunc(s []byte, f func(r rune) bool) []byte
// 返回将s前后端所有满足f函数条件的值都去掉的新切片
fmt.Println(string(bytes.TrimFunc([]byte("hhi go"),func(r rune) bool {
return r == 'h' || r == 'o'
}))) // i g;
// func TrimLeftFunc(s []byte, f func(r rune) bool) []byte
// 返回将s左边所有满足函数f的值都去掉的新切片,与TrimFunc类似,不在演示
// func TrimRightFunc(s []byte, f func(r rune) bool) []byte
// 返回将s右边所有满足函数f的值都去掉的新切片,与TrimFunc类似,不在演示
至此,bytes包95%的工具方法都介绍完了。下一节再介绍bytes包读取buffer的知识