golang源码阅读-bytes.NewBuffer

1.基本使用

func main() {
	var byteArr []byte
	buf := bytes.NewBuffer(byteArr)
	buf.Write([]byte("今天不错"))

	fmt.Println(buf.String())
}

2. NewBuffer

源码:

func NewBuffer(buf []byte) *Buffer {
//返回Buffer 结构体实例 传入buf 存到buf中
//type Buffer struct {
//	buf      []byte
//	off      int
//  lastRead readOp
//}
	return &Buffer{
		buf: buf,
	}
}

3.Write

源码:

func (b *Buffer) Write(p []byte) (n int, err error) {
//设置为没有读操作
	b.lastRead = opInvalid

//判断是否需要扩容
	m, ok := b.tryGrowByReslice(len(p))
	if !ok {
//扩容
		m = b.grow(len(p))
	}

//传入p复制到buf数组后
	return copy(b.buf[m:], p), nil
}

4. tryGrowByReslice

源码:

func (b *Buffer) tryGrowByReslice(n int) (int, bool) {
//l为buf数组长度   n 小于 buf容量减去 已用的长度   就是不用扩容
	if l := len(b.buf); n <= cap(b.buf)-l {
       //长度变长 但是没有扩容
		b.buf = b.buf[:l+n]
		return l, true
	}

	return 0, false
}

5. grow 扩容

源码:

func (b *Buffer) grow(n int) int {
// 可用的长度, buf长度减去 偏移量
	m := b.Len()
    //可用为0 进行重置
	if m == 0 && b.off != 0 {
		b.Reset()
	}
    //是否需要扩容
	if i, ok := b.tryGrowByReslice(n); ok {
		return i
	}

    //如果buf为空 并且传入的长度 小于 自定义最小的长度
	if b.buf == nil && n <= smallBufferSize {
       //创建一个
		b.buf = make([]byte, n, smallBufferSize)
		return 0
	}

//获取容量
	c := cap(b.buf)

//如果传入长度n 小于等于  容量一半 减去 可用的
	if n <= c/2-m {
//不需要扩容 复制内容
		copy(b.buf, b.buf[b.off:])
	} else if c > maxInt-c-n {
		panic(ErrTooLarge)
	} else {
        //生成长度为 容量2倍 + 传入长度 n 的数组
		buf := makeSlice(2*c + n)
// 复制已经存入的内容
		copy(buf, b.buf[b.off:])
//复制
		b.buf = buf

	}
//off重置为0
	b.off = 0
//长度变为容量 +n
	b.buf = b.buf[:m+n]
//返回已用的长度
	return m
}

 

你可能感兴趣的:(golang)