Golang -- 字节切片

前端之家收集整理的这篇文章主要介绍了Golang -- 字节切片前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Go 语言标准库 bytes ,实现了对字节数组的各种操作。 It is analogous to the facilities of strings package. (它和string 标准包提供的功能类似)
提供的功能如下;

字节切片处理函数


基本处理函数 共七个

  1. Contains() 返回是否包含子切片
  2. Count() 子切片非重叠实例的数量
  3. Map() 函数,将byte 转化为Unicode,然后进行替换
  4. Repeat() 将切片复制count此,返回这个新的切片
  5. Replace() 将切片中的一部分 替换为另外的一部分
  6. Runes() 将 S 转化为对应的 UTF-8 编码的字节序列,并且返回对应的Unicode 切片
  7. Join() 函数,将子字节切片连接到一起。

func Contains(b,subslice []byte) bool

func Contains(b,subslice [] byte) bool 检查字节切片 b ,是否包含子字节切片 subslice

package main

import (
    "bytes"
    "fmt"
)

func main() {
    @H_301_73@// 这里不能写成 b := []byte{"Golang"},这里是利用类型转换。
    b := []byte("Golang")
    subslice1 := []byte("go")
    subslice2 := []byte("Go")
    fmt.Println(bytes.Contains(b,subslice1))
    fmt.Println(bytes.Contains(b,subslice2))
}

Counts(s,spe[ []byte) int

func Count(s,sep []byte) int 计算子字节切片 sep 在字节切片 s 中出现的非重叠实例的数量

package main

import (
    "bytes"
    "fmt"
)

func main() { s := []byte("banana") sep1 := []byte("ban") sep2 := []byte("na") sep3 := []byte("a") fmt.Println(bytes.Count(s,sep1)) fmt.Println(bytes.Count(s,sep2)) fmt.Println(bytes.Count(s,sep3)) }

func Map(mapping func(r rune) rune,s []byte) []byte

Map函数:首先将 s 转化为 UTF-8编码的字符序列,然后使用 mapping 将每个Unicode字符映射为对应的字符,最后将结果保存在一个新的字节切片中。

package main

import (
    "bytes"
    "fmt"
)

func main() {

    s := []byte("同学们,上午好")
    m := func(r rune) rune {
        if r == '上' {
            r = '下'
        }
        return r
    }
    fmt.Println(string(s))
    fmt.Println(string(bytes.Map(m,s)))
}

func Repeat(b []byte,count int) []byte

func Replace(s,old,new []byte,n int) []byte

返回字节切片 S 的一个副本, 并且将前n个不重叠的子切片 old 替换为 new,如果n < 0 那么不限制替换的数量

package main

import (
    "bytes"
    "fmt"
)

func main() {
    s := []byte("google")
    old := []byte("o")
    @H_301_73@//这里 new 是一个字节切片,不是关键字了
    new := []byte("oo")
    n := 1
    fmt.Println(string(bytes.Replace(s,new,n)))
    fmt.Println(string(bytes.Replace(s, -1)))
}

func Runes(b []byte) []rune

将字节切片 转化为对应的 UTF-8编码的字节序列,并且返回对应的 Unicode 切片。

package main

import (
    "bytes"
    "fmt"
)
@H_301_73@//每个 rune 变量占据 4个字节,等价于 int32
@H_301_73@//每个 byte 变量占据1个字节,等价于int8
func main() {
    s := []byte("中华人民共和国")
    r := bytes.Runes(s)
    fmt.Println(string(s),len(s))  @H_301_73@//字节切片的长度
    fmt.Println(string(r),len(r))   @H_301_73@// rune 切片的长度
}

func Join(s [][]byte,sep []byte) []byte

用字节切片 sep 吧 s中的每个字节切片连接成一个,并且返回.

package main

import (
    "bytes"
    "fmt"
)

func main() {
    @H_301_73@// 字节切片 的每个元素,依旧是字节切片。
    s := [][]byte{
        []byte("你好"),[]byte("世界"),@H_301_73@//这里的逗号,必不可少
    }
    sep := []byte(",")
    fmt.Println(string(bytes.Join(s,sep)))

    var a = []int{1, 2, 3, 5,@H_301_73@//这里的逗号,也必不可少
    }
    fmt.Println(a)

    var b = []int{1, 4, 5}  @H_301_73@//这里最后一个元素不需要逗号
    fmt.Println(b)
}

字节切片比较函数

func Compare(a,b[]byte) int : 返回整数:1,-1
func Equal(a,b []byte) bool: 返回true or false
func EqualFold(a,b []byte) bool : 忽略大小写:返回 true or false

package main

import (
    "bytes"
    "fmt"
)

func main() {
    a := []byte("abc")
    b := []byte("ABC")
    s := []byte("GOLANG")
    t := []byte("golang")

    fmt.Println(bytes.Compare(a,b))
    fmt.Println(bytes.Equal(a,b))
    fmt.Println(bytes.EqualFold(s,t))
}
输出为:
1
false
true

字节切片 前后缀 检查函数

func HasPreifx(s,prefix []byte) bool
func HasSuffix(s,suffix []byte) bool

字节切片 位置索引函数

  • func Index(s,sep []byte) int 返回字节切片在s中第一次出现的位置(索引从0 开始),不存在返回-1.
  • func IndexAny(s []byte,chars string) 将字节切片解释为 UTF-8的字符,返回 chars 中任何一个字符在s中 第一次出现的位置。(chars 中保存的是 Unicode字符集)
  • func IndexByte(s []byte,c byte) int
  • func IndexFunc(s []byte,f func(r rune)bool) int 将 s 解释成 UTF-8字节序列, 并且返回第一个使得 f(c) = ture的字符 c的索引位置。
  • func IndexRue(s []byte,r rune)
  • func LastIndex(s,sep []byte) int
  • func LastIndexAny (s []byte,chars string) int
  • func LastIndexFunc(s []byte,f func(r rune) bool) int

字节切片 分割函数

  • func Fields(s []byte) [][]byte 将字节切片 s 按照 一个或者连续多个空白字符 分割成 多个字节切片。如果 s 只包含空白字符,则返回 空字节切片。
package main

import (
    "bytes"
    "fmt"
)

func main() {
    s := []byte(" I'm a student. ")
    for _,f := range bytes.Fields(s) {
        fmt.Printf("%q ",f)
    }

    s1 := []byte(" ")
    s2 := bytes.Fields(s1)

    fmt.Println(len(s2),s2 == nil)
}
程序输出如下:
"I'm" "a" "student." 0 false
  • func FieldsFunc(s []byte,f func(r rune) bool) [][]byte, 首先将s 解释成 Unicode 字符序列,然后用函数 f 进行测试。
  • func Split(s,sep []byte) [][]byte 按照字节序列 sep 进行分割
  • func SplitN(s,sep []byte,n int) [][]byte 按照字节序列 sep 进行分割,并且 可以设置 分割成的字节切片的个数,n == -1表示返回所有的子切片。
  • func SplitAfter(s,sep[] byte) [][]byte,这里是不舍弃 sep,而是保留sep。
  • func SplitAfterN(s,sep[] byte,int n) [][]byte 和上次是一样的。

    字节切片大小写处理函数

    • func Title(s []byte) []byte 返回s的一个副本,并且将S中每个单词的首字母转化成 Unicode大写字符。
    • func ToTitle(s []byte) []byte 将其中的所有Unicode字符转化成大写。
    • func ToTitleSpecial(_case unicode.SpecialCase,s []byte) []byte
    • func ToLower(s []byte) []byte
    • func ToLowerSpeical(_case unicode.SpecialCase,s[]byte) []byte
    • func ToUpper(s []byte) []byte
    • func ToUpperSpecial (_case unicode.SpecialCase,s []byte) []byte

子字节 切片 处理函数

将 一个 字节切片截端,然后返回新的字节切片

func Trim(s []byte,cutset string) []byte
func TrimFunc(s []byte,f func(r rune) bool) []byte
func TrimLeft(s []byte,cutset string) []byte
func TrimLeftFunc(s []byte,f func(r rune) bool) []byte
func TrimRight(s []byte,cutset string) []byte
func TrimRightFunc (s []byte,f func(r rune) bool) []byte
func TrimPrefix(s,prefix []byte) []byte
func TrimSuffix(s,suffix []byte) []byte
func TrimSpace(s []byte) []byte

Buffer and Reader

现在需要对字节切片进行读写: 比如说,不停地向字节切片中 写入字符串, 从字节切片中读取字符串等等操作。
于是我们有了 Buffer and Reader.


bytes.Buffer

Buffer 是 bytes 包中的一个 type Buffer struct{…}

A buffer is a variable-sized buffer of bytes with Read and Write methods. The zero value for Buffer is an empty buffer ready to use. (是一个变长的 buffer,具有 Read 和Write 方法。 Buffer 的 零值 是一个 空的 buffer,但是可以使用)
在我看来: Buffer 是一种抽象,想想成一个不限容量蓄水池,你可以向其中加水,同时也可以向其中取出水。(存入数据,和取数据)

  1. 创建 一个 Buffer (其实底层就是一个 []byte, 字节切片)
  2. 向其中写入数据 (Write mtheods)
  3. 从其中读取数据 (Write methods)

创建 Buffer

var b bytes.Buffer  @H_301_73@//直接定义一个 Buffer 变量,而不用初始化
b.Writer([]byte("Hello ")) @H_301_73@// 可以直接使用

b1 := new(bytes.Buffer)   @H_301_73@//直接使用 new 初始化,可以直接使用
@H_301_73@// 其它两种定义方式
func NewBuffer(buf []byte) *Buffer
func NewBufferString(s string) *Buffer

Buffer 基本函数

func (b *Buffer) Bytes() []byte 返回 没有读取的 内容
func (b *Buffer) Grow() (n int) 增加 buffer 的容量
func (b *Buffer) Len() int 返回没有读取的内容的长度
func (b *Buffer) Next(n int) []byte 返回没有读取的 n个字节,副作用,就像采用了Read 方法进行了读一样。

向 Buffer 中读取数据

func (*Buffer) Read(p []byte) (n int,err error) 从 Buffer 从读取 len(p) 的数据,直到 Buffer 没有数据可以读取。 返回值是读取数据的字节数。 如果没有数据可以读取,那么err 的值是 io.EOF
func (*Buffer) ReadByte() (c byte,err error)
func (*Buffer) ReadBytes(delim byte) (line []byte,err error) 遇到第一个 delim 的时候,将数据返回。
func (*Buffer)ReadRune() (r rune,err error)
func (*Buffer) ReadString(delim byte) (line string,err error)
func (*Buffer) Reset() 将数据清空,没有数据可读
func (*Buffer) String() string 将未读取的数据返回成 string

func (*Buffer) Truncate(n int) 在Buffer中保留 n个未读的数据。

func (*Buffer) UnreadByte() error
func (*Buffer) UnreadRune() error 小心返回错误

func (*Buffer) ReadFrom( r o.Reader) (n int64,err error) 从 IO 接口 对象 r中读取数据,并且写入到 buffer中,知道 r.Read 返回 io.EOF。 (当然)

向 Buffer 中写入数据

func (b * Buffer) Write(p []byte) (n int,err error)把字节切片 p 写入到buffer中去。
func (b *Buffer) WriteByte(c byte) error
func (b *Buffer) WriteRune(c byte) error
func (b *Buffer) WriteString(s string) (n int,err error)
func (b *Buffer) WriteTo(w io.Writer) (n int64,err error) 将Buffer 中的数据写入到 I/O对象 writer 中去,知道数据为空,或者遇到错误


bytes.Reader

Reader 是另外一个可以对切片进行操作的方法,但是 Reader只可以对数据进行 读取操作,不从向切片中写入数据。Reader 支持对切片进行Seek() 定位 操作。


总结

说明了一下几点: 1. []byte 字节切片是 golang中的(最)重要的工具,好好利用字节切片 2. 掌握好对字节切片进行操作的工具。 (有好的工具很重要) 3. 多多写程序,才可以有收获

原文链接:https://www.f2er.com/go/190477.html

猜你在找的Go相关文章