Go源码学习:bytes包 - 1.1 - buffer.go -(4)

本文详细解析了Go语言Bytes包中的几个关键方法,如UnreadRune和UnreadByte用于撤销读取操作,ReadBytes和readSlice用于读取定界符,以及NewBuffer和NewBufferString用于创建初始化缓冲区。这些方法有助于理解和操作Go的内存管理与输入/输出操作。
摘要由CSDN通过智能技术生成

bytes包官方文档

Go源码学习-索引目录

上一篇:
Go源码学习:bytes包 - 1.2 - buffer.go -(3)

31、UnreadRune:撤销最后一个读取的符文

// UnreadRune 撤销最后一个由 [Buffer.ReadRune] 返回的符文。
// 如果缓冲区上最近的读取或写入操作不是成功的 [Buffer.ReadRune],UnreadRune 将返回错误。
// (在这方面,它比 [Buffer.UnreadByte] 更严格,后者将从任何读取操作中撤消最后一个字节。)
func (b *Buffer) UnreadRune() error {
    // 如果最近的读取操作无效,表示不是成功的 ReadRune,返回错误。
    if b.lastRead <= opInvalid {
        return errors.New("bytes.Buffer: UnreadRune: previous operation was not a successful ReadRune")
    }
    // 如果读取偏移量超过了最近读取的位置,将偏移量减去最近读取的位置。
    if b.off >= int(b.lastRead) {
        b.off -= int(b.lastRead)
    }
    // 将最近读取的标志设为无效。
    b.lastRead = opInvalid
    return nil
}

解释:

  • UnreadRune 方法是 Buffer 结构体的方法,用于撤销最后一个由 Buffer.ReadRune 返回的符文。
  • 首先,检查最近的读取操作是否为成功的 ReadRune,如果不是,返回相应错误。
  • 如果读取偏移量超过了最近读取的位置,将偏移量减去最近读取的位置。
  • 将最近读取的标志设为无效,表示已经撤销了最后一个读取的符文。

作用:

  • UnreadRune 方法用于在符文读取后撤销该符文,以便重新读取。
  • 通过检查最近的读取操作是否为成功的 ReadRune,确保只有成功读取的符文才能被撤销。

32、UnreadByte:撤销最后一个字节的读取

var errUnreadByte = errors.New("bytes.Buffer: UnreadByte: previous operation was not a successful read")

// UnreadByte 撤销最后一个由最近成功读取的操作返回的字节。
// 如果自上次读取以来发生写入,如果最后一次读取返回错误,或者如果读取了零字节,UnreadByte 将返回错误。
func (b *Buffer) UnreadByte() error {
    // 如果最近的读取操作无效,表示不是成功的读取,返回相应错误。
    if b.lastRead == opInvalid {
        return errUnreadByte
    }
    // 将最近读取的标志设为无效。
    b.lastRead = opInvalid
    // 如果偏移量大于零,将偏移量减一。
    if b.off > 0 {
        b.off--
    }
    return nil
}

解释:

  • UnreadByte 方法是 Buffer 结构体的方法,用于撤销最后一个由最近成功读取的操作返回的字节。
  • 首先,检查最近的读取操作是否为成功的读取,如果不是,返回相应错误。
  • 将最近读取的标志设为无效,表示已经撤销了最后一个字节的读取。
  • 如果偏移量大于零,将偏移量减一。

作用:

  • UnreadByte 方法用于在字节读取后撤销该字节的读取,以便重新读取。
  • 通过检查最近的读取操作是否为成功的读取,确保只有成功读取的字节才能被撤销。

33、ReadBytes:读取字节直到定界符

// ReadBytes 读取输入中第一个定界符之前的数据,
// 返回一个包含数据和定界符的切片。
// 如果在找到定界符之前发生错误,返回错误之前读取的数据和错误本身(通常是 io.EOF)。
// 当且仅当返回的数据不以定界符结束时,ReadBytes 返回 err != nil。
func (b *Buffer) ReadBytes(delim byte) (line []byte, err error) {
    // 调用 readSlice 方法获取切片和错误。
    slice, err := b.readSlice(delim)
    // 返回切片的副本。缓冲区的底层数组可能被后续调用覆盖。
    line = append(line, slice...)
    return line, err
}

解释:

  • ReadBytes 方法是 Buffer 结构体的方法,用于读取输入中第一个定界符之前的数据,并返回包含数据和定界符的切片。
  • 调用了 readSlice 方法获取切片和可能的错误。
  • 返回切片的副本,因为缓冲区的底层数组可能被后续调用覆盖。

作用:

  • ReadBytes 方法用于读取数据直到指定定界符,并返回包含定界符在内的数据切片。

34、readSlice:读取切片引用内部缓冲区数据

// readSlice 类似于 ReadBytes,但返回对内部缓冲区数据的引用。
func (b *Buffer) readSlice(delim byte) (line []byte, err error) {
    // 在当前读取偏移量 b.off 后的缓冲区中查找定界符的索引。
    i := IndexByte(b.buf[b.off:], delim)
    // 计算定界符的结束位置。
    end := b.off + i + 1
    // 如果没有找到定界符,设置结束位置为缓冲区末尾,并将错误设置为 io.EOF。
    if i < 0 {
        end = len(b.buf)
        err = io.EOF
    }
    // 提取从当前偏移量到结束位置的数据切片。
    line = b.buf[b.off:end]
    // 更新偏移量和最近读取的标志。
    b.off = end
    b.lastRead = opRead
    return line, err
}

解释:

  • readSlice 方法类似于 ReadBytes,但返回对内部缓冲区数据的引用。
  • 在当前读取偏移量 b.off 后的缓冲区中查找定界符的索引。
  • 计算定界符的结束位置,并提取从当前偏移量到结束位置的数据切片。
  • 如果没有找到定界符,设置结束位置为缓冲区末尾,并将错误设置为 io.EOF
  • 更新偏移量和最近读取的标志。

作用:

  • readSlice 方法用于读取数据直到指定定界符,并返回对内部缓冲区数据的引用。

35、ReadString:读取字符串直到定界符

// ReadString 读取输入中第一个定界符之前的数据,
// 返回一个包含数据和定界符的字符串。
// 如果在找到定界符之前发生错误,返回错误之前读取的数据和错误本身(通常是 io.EOF)。
// 当且仅当返回的数据不以定界符结束时,ReadString 返回 err != nil。
func (b *Buffer) ReadString(delim byte) (line string, err error) {
    // 调用 readSlice 方法获取切片和错误。
    slice, err := b.readSlice(delim)
    // 将切片转换为字符串。
    return string(slice), err
}

解释:

  • ReadString 方法是 Buffer 结构体的方法,用于读取输入中第一个定界符之前的数据,并返回包含数据和定界符的字符串。
  • 调用了 readSlice 方法获取切片和可能的错误。
  • 将切片转换为字符串并返回。

作用:

  • ReadString 方法用于读取数据直到指定定界符,并返回包含定界符在内的字符串。

36、NewBuffer:创建并初始化新的缓冲区

// NewBuffer 创建并初始化一个新的 [Buffer],使用 buf 作为其初始内容。
// 新的 [Buffer] 接管 buf,并且调用方在此调用后不应再使用 buf。
// NewBuffer 用于准备 [Buffer] 以读取现有数据。也可以用于设置用于写入的内部缓冲区的初始大小。
// 为了实现这一点,buf 应具有所需容量但长度为零。
//
// 在大多数情况下,new([Buffer])(或只是声明 [Buffer] 变量)足以初始化 [Buffer]。
func NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} }

解释:

  • NewBuffer 函数创建并初始化一个新的 Buffer,使用 buf 作为其初始内容。
  • 新的 Buffer 接管 buf,调用方在此调用后不应再使用 buf
  • 用于准备 Buffer 以读取现有数据,也可以用于设置用于写入的内部缓冲区的初始大小。

作用:

  • NewBuffer 用于创建和初始化新的缓冲区,可以指定初始内容。

37、NewBufferString:创建并初始化新的缓冲区(使用字符串)

// NewBufferString 创建并初始化一个新的 [Buffer],使用字符串 s 作为其初始内容。
// 用于准备缓冲区以读取现有字符串。
//
// 在大多数情况下,new([Buffer])(或只是声明 [Buffer] 变量)足以初始化 [Buffer]。
func NewBufferString(s string) *Buffer {
    return &Buffer{buf: []byte(s)}
}

解释:

  • NewBufferString 函数创建并初始化一个新的 Buffer,使用字符串 s 作为其初始内容。
  • 用于准备缓冲区以读取现有字符串。

作用:

  • NewBufferString 用于创建和初始化新的缓冲区,可以指定初始内容为字符串。
  • 27
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

风不归Alkaid

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

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

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

打赏作者

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

抵扣说明:

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

余额充值