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
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章