当前位置: 代码迷 >> 综合 >> Golang bytes源码分析
  详细解决方案

Golang bytes源码分析

热度:78   发布时间:2024-02-08 12:07:48.0

bytes/bytes.go源码分析

Golang JDK 1.10.3

bytes包提供了操作[]byte的常用方法。

 

源码分析

func equalPortable(a, b []byte) bool {if len(a) != len(b) {return false}for i, c := range a {if c != b[i] {return false}}return true
}

equalPortable函数是内部函数,用于比较两个切片的元素是否相等。

 

// explode splits s into a slice of UTF-8 sequences, one per Unicode code point (still slices of bytes),
// up to a maximum of n byte slices. Invalid UTF-8 sequences are chopped into individual bytes.
func explode(s []byte, n int) [][]byte {if n <= 0 {n = len(s)}a := make([][]byte, n)var size intna := 0for len(s) > 0 {if na+1 >= n {a[na] = sna++break}_, size = utf8.DecodeRune(s)a[na] = s[0:size:size]s = s[size:]na++}return a[0:na]
}

explode函数是内部函数,用于将字节切片s转成 UTF-8序列

 

// countGeneric actually implements Count
func countGeneric(s, sep []byte) int {// special caseif len(sep) == 0 {return utf8.RuneCount(s) + 1}n := 0for {i := Index(s, sep)if i == -1 {return n}n++s = s[i+len(sep):]}
}

countGeneric函数也是内部函数,用于返回sep在s中出现的次数。如果sep为空,则返回s的rune长度+1

 

// Contains reports whether subslice is within b.
func Contains(b, subslice []byte) bool {return Index(b, subslice) != -1
}

作用:b中是否包含subslice切片

 

// ContainsAny reports whether any of the UTF-8-encoded code points in chars are within b.
func ContainsAny(b []byte, chars string) bool {return IndexAny(b, chars) >= 0
}

作用:判断切片b中是否包含字符串chanrs

 

// ContainsRune reports whether the rune is contained in the UTF-8-encoded byte slice b.
func ContainsRune(b []byte, r rune) bool {return IndexRune(b, r) >= 0
}

作用:判断字节切片b中是否包含UTF-8字符r

 

func indexBytePortable(s []byte, c byte) int {for i, b := range s {if b == c {return i}}return -1
}
indexBytePortable函数用于返回c在s中第一次出现的索引,如果在切片s中,则返回-1

 

// LastIndex returns the index of the last instance of sep in s, or -1 if sep is not present in s.
func LastIndex(s, sep []byte) int {n := len(sep)if n == 0 {return len(s)}c := sep[0]for i := len(s) - n; i >= 0; i-- {if s[i] == c && (n == 1 || Equal(s[i:i+n], sep)) {return i}}return -1
}

LastIndex函数用于获取sep在s中反向第一次出现的索引,子切片sep不包含在切片s中,则返回-1

 

// LastIndexByte returns the index of the last instance of c in s, or -1 if c is not present in s.
func LastIndexByte(s []byte, c byte) int {for i := len(s) - 1; i >= 0; i-- {if s[i] == c {return i}}return -1
}

作用:获取字节c在切片s中倒序第一次出现的索引

 

// IndexRune interprets s as a sequence of UTF-8-encoded code points.
// It returns the byte index of the first occurrence in s of the given rune.
// It returns -1 if rune is not present in s.
// If r is utf8.RuneError, it returns the first instance of any
// invalid UTF-8 byte sequence.
func IndexRune(s []byte, r rune) int {switch {case 0 <= r && r < utf8.RuneSelf:return IndexByte(s, byte(r))case r == utf8.RuneError:for i := 0; i < len(s); {r1, n := utf8.DecodeRune(s[i:])if r1 == utf8.RuneError {return i}i += n}return -1case !utf8.ValidRune(r):return -1default:var b [utf8.UTFMax]byten := utf8.EncodeRune(b[:], r)return Index(s, b[:n])}
}

作用:获取UTF-8字符r在字节切片s中第一次出现的索引,不包含在切片s中返回-1

 

// IndexAny interprets s as a sequence of UTF-8-encoded Unicode code points.
// It returns the byte index of the first occurrence in s of any of the Unicode
// code points in chars. It returns -1 if chars is empty or if there is no code
// point in common.
func IndexAny(s []byte, chars string) int {if chars == "" {// Avoid scanning all of s.return -1}if len(s) > 8 {if as, isASCII := makeASCIISet(chars); isASCII {for i, c := range s {if as.contains(c) {return i}}return -1}}var width intfor i := 0; i < len(s); i += width {r := rune(s[i])if r < utf8.RuneSelf {width = 1} else {r, width = utf8.DecodeRune(s[i:])}for _, ch := range chars {if r == ch {return i}}}return -1
}

作用:查找字符串 chars 中的任何一个字符在 切片s 中第一次出现的位置,找不到则返回 -1

 

// LastIndexAny interprets s as a sequence of UTF-8-encoded Unicode code
// points. It returns the byte index of the last occurrence in s of any of
// the Unicode code points in chars. It returns -1 if chars is empty or if
// there is no code point in common.
func LastIndexAny(s []byte, chars string) int {if chars == "" {// Avoid scanning all of s.return -1}if len(s) > 8 {if as, isASCII := makeASCIISet(chars); isASCII {for i := len(s) - 1; i >= 0; i-- {if as.contains(s[i]) {return i}}return -1}}for i := len(s); i > 0; {r, size := utf8.DecodeLastRune(s[:i])i -= sizefor _, c := range chars {if r == c {return i}}}return -1
}

作用:查找 chars 中的任何一个字符在 s 中最后一次出现的位置,找不到则返回 -1

 

// Generic split: splits after each instance of sep,
// including sepSave bytes of sep in the subslices.
func genSplit(s, sep []byte, sepSave, n int) [][]byte {if n == 0 {return nil}if len(sep) == 0 {return explode(s, n)}if n < 0 {n = Count(s, sep) + 1}a := make([][]byte, n)n--i := 0for i < n {m := Index(s, sep)if m < 0 {break}a[i] = s[: m+sepSave : m+sepSave]s = s[m+len(sep):]i++}a[i] = sreturn a[:i+1]
}

genSplit函数,根据sep拆分s,sepSave是子切片中含有+sepSave个字节数,n是切分的个数,n如果是负数则都进行切分

 

// SplitN slices s into subslices separated by sep and returns a slice of
// the subslices between those separators.
// If sep is empty, SplitN splits after each UTF-8 sequence.
// The count determines the number of subslices to return:
//   n > 0: at most n subslices; the last subslice will be the unsplit remainder.
//   n == 0: the result is nil (zero subslices)
//   n < 0: all subslices
func SplitN(s, sep []byte, n int) [][]byte { return genSplit(s, sep, 0, n) }

作用:将切片s根据sep切分成n个切片,注:切分后不含分隔符sep

 

// SplitAfterN slices s into subslices after each instance of sep and
// returns a slice of those subslices.
// If sep is empty, SplitAfterN splits after each UTF-8 sequence.
// The count determines the number of subslices to return:
//   n > 0: at most n subslices; the last subslice will be the unsplit remainder.
//   n == 0: the result is nil (zero subslices)
//   n < 0: all subslices
func SplitAfterN(s, sep []byte, n int) [][]byte {return genSplit(s, sep, len(sep), n)
}

作用:将切片s根据sep切分成n个切片,切分后包含分隔符sep

 

// Split slices s into all subslices separated by sep and returns a slice of
// the subslices between those separators.
// If sep is empty, Split splits after each UTF-8 sequence.
// It is equivalent to SplitN with a count of -1.
func Split(s, sep []byte) [][]byte { return genSplit(s, sep, 0, -1) }

作用:将切片s根据sep进行切分,切分后不包含分隔符sep

 

// SplitAfter slices s into all subslices after each instance of sep and
// returns a slice of those subslices.
// If sep is empty, SplitAfter splits after each UTF-8 sequence.
// It is equivalent to SplitAfterN with a count of -1.
func SplitAfter(s, sep []byte) [][]byte {return genSplit(s, sep, len(sep), -1)
}

作用:将s根据sep进行切分,切分后包含分隔符sep

 

// Fields interprets s as a sequence of UTF-8-encoded code points.
// It splits the slice s around each instance of one or more consecutive white space
// characters, as defined by unicode.IsSpace, returning a slice of subslices of s or an
// empty slice if s contains only white space.
func Fields(s []byte) [][]byte {// First count the fields.// This is an exact count if s is ASCII, otherwise it is an approximation.n := 0wasSpace := 1// setBits is used to track which bits are set in the bytes of s.setBits := uint8(0)for i := 0; i < len(s); i++ {r := s[i]setBits |= risSpace := int(asciiSpace[r])n += wasSpace & ^isSpacewasSpace = isSpace}if setBits >= utf8.RuneSelf {// Some runes in the input slice are not ASCII.return FieldsFunc(s, unicode.IsSpace)}// ASCII fast patha := make([][]byte, n)na := 0fieldStart := 0i := 0// Skip spaces in the front of the input.for i < len(s) && asciiSpace[s[i]] != 0 {i++}fieldStart = ifor i < len(s) {if asciiSpace[s[i]] == 0 {i++continue}a[na] = s[fieldStart:i:i]na++i++// Skip spaces in between fields.for i < len(s) && asciiSpace[s[i]] != 0 {i++}fieldStart = i}if fieldStart < len(s) { // Last field might end at EOF.a[na] = s[fieldStart:len(s):len(s)]}return a
}

作用:将s切片 根据  \t或\n或\v或\f 或\r或空格进行切分

 

// FieldsFunc interprets s as a sequence of UTF-8-encoded code points.
// It splits the slice s at each run of code points c satisfying f(c) and
// returns a slice of subslices of s. If all code points in s satisfy f(c), or
// len(s) == 0, an empty slice is returned.
// FieldsFunc makes no guarantees about the order in which it calls f(c).
// If f does not return consistent results for a given c, FieldsFunc may crash.
func FieldsFunc(s []byte, f func(rune) bool) [][]byte {// A span is used to record a slice of s of the form s[start:end].// The start index is inclusive and the end index is exclusive.type span struct {start intend   int}spans := make([]span, 0, 32)// Find the field start and end indices.wasField := falsefromIndex := 0for i := 0; i < len(s); {size := 1r := rune(s[i])if r >= utf8.RuneSelf {r, size = utf8.DecodeRune(s[i:])}if f(r) {if wasField {spans = append(spans, span{start: fromIndex, end: i})wasField = false}} else {if !wasField {fromIndex = iwasField = true}}i += size}// Last field might end at EOF.if wasField {spans = append(spans, span{fromIndex, len(s)})}// Create subslices from recorded field indices.a := make([][]byte, len(spans))for i, span := range spans {a[i] = s[span.start:span.end:span.end]}return a
}

作用:将切片s根据f函数进行切分

 

// Join concatenates the elements of s to create a new byte slice. The separator
// sep is placed between elements in the resulting slice.
func Join(s [][]byte, sep []byte) []byte {if len(s) == 0 {return []byte{}}if len(s) == 1 {// Just return a copy.return append([]byte(nil), s[0]...)}n := len(sep) * (len(s) - 1)for _, v := range s {n += len(v)}b := make([]byte, n)bp := copy(b, s[0])for _, v := range s[1:] {bp += copy(b[bp:], sep)bp += copy(b[bp:], v)}return b
}

作用:将s根据sep进行连接,sep是连接符

 

// HasPrefix tests whether the byte slice s begins with prefix.
func HasPrefix(s, prefix []byte) bool {return len(s) >= len(prefix) && Equal(s[0:len(prefix)], prefix)
}

作用:判断s是否是以prefix开头

 

// HasSuffix tests whether the byte slice s ends with suffix.
func HasSuffix(s, suffix []byte) bool {return len(s) >= len(suffix) && Equal(s[len(s)-len(suffix):], suffix)
}

作用:判断切片s是否是以suffix结尾

 

// Map returns a copy of the byte slice s with all its characters modified
// according to the mapping function. If mapping returns a negative value, the character is
// dropped from the byte slice with no replacement. The characters in s and the
// output are interpreted as UTF-8-encoded code points.
func Map(mapping func(r rune) rune, s []byte) []byte {// In the worst case, the slice can grow when mapped, making// things unpleasant. But it's so rare we barge in assuming it's// fine. It could also shrink but that falls out naturally.maxbytes := len(s) // length of bnbytes := 0        // number of bytes encoded in bb := make([]byte, maxbytes)for i := 0; i < len(s); {wid := 1r := rune(s[i])if r >= utf8.RuneSelf {r, wid = utf8.DecodeRune(s[i:])}r = mapping(r)if r >= 0 {rl := utf8.RuneLen(r)if rl < 0 {rl = len(string(utf8.RuneError))}if nbytes+rl > maxbytes {// Grow the buffer.maxbytes = maxbytes*2 + utf8.UTFMaxnb := make([]byte, maxbytes)copy(nb, b[0:nbytes])b = nb}nbytes += utf8.EncodeRune(b[nbytes:maxbytes], r)}i += wid}return b[0:nbytes]
}

作用:将切片s根据映射函数mapping生成新的切片

 

// Repeat returns a new byte slice consisting of count copies of b.
//
// It panics if count is negative or if
// the result of (len(b) * count) overflows.
func Repeat(b []byte, count int) []byte {// Since we cannot return an error on overflow,// we should panic if the repeat will generate// an overflow.// See Issue golang.org/issue/16237.if count < 0 {panic("bytes: negative Repeat count")} else if count > 0 && len(b)*count/count != len(b) {panic("bytes: Repeat count causes overflow")}nb := make([]byte, len(b)*count)bp := copy(nb, b)for bp < len(nb) {copy(nb[bp:], nb[:bp])bp *= 2}return nb
}

作用:填充count个b切片,即返回的切片有count个切片b填充,返回切片的长度为:len(b)*count

 

// ToUpper treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters within it mapped to their upper case.
func ToUpper(s []byte) []byte { return Map(unicode.ToUpper, s) }

作用:将切片中的每个字节元素转成大写

 

// ToLower treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their lower case.
func ToLower(s []byte) []byte { return Map(unicode.ToLower, s) }

作用:将切片中的每个字节元素转成小写

 

// ToTitle treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their title case.
func ToTitle(s []byte) []byte { return Map(unicode.ToTitle, s) }

作用:将切片 s 中的所有字符修改为标题格式返回

 

// ToUpperSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
// upper case, giving priority to the special casing rules.
func ToUpperSpecial(c unicode.SpecialCase, s []byte) []byte {return Map(func(r rune) rune { return c.ToUpper(r) }, s)
}

作用:使用指定的映射表将 s 中的所有字符修改为大写格式返回。

 

// ToLowerSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
// lower case, giving priority to the special casing rules.
func ToLowerSpecial(c unicode.SpecialCase, s []byte) []byte {return Map(func(r rune) rune { return c.ToLower(r) }, s)
}

作用:使用指定的映射表将 s 中的所有字符修改为小写格式返回。

 

// ToTitleSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
// title case, giving priority to the special casing rules.
func ToTitleSpecial(c unicode.SpecialCase, s []byte) []byte {return Map(func(r rune) rune { return c.ToTitle(r) }, s)
}

作用:使用指定的映射表将 切片 s 中的所有字符修改为标题格式返回。

 

// isSeparator reports whether the rune could mark a word boundary.
// TODO: update when package unicode captures more of the properties.
func isSeparator(r rune) bool {// ASCII alphanumerics and underscore are not separatorsif r <= 0x7F {switch {case '0' <= r && r <= '9':return falsecase 'a' <= r && r <= 'z':return falsecase 'A' <= r && r <= 'Z':return falsecase r == '_':return false}return true}// Letters and digits are not separatorsif unicode.IsLetter(r) || unicode.IsDigit(r) {return false}// Otherwise, all we can do for now is treat spaces as separators.return unicode.IsSpace(r)
}

isSeparator方法判断是否是分隔符

 

// Title treats s as UTF-8-encoded bytes and returns a copy with all Unicode letters that begin
// words mapped to their title case.
//
// BUG(rsc): The rule Title uses for word boundaries does not handle Unicode punctuation properly.
func Title(s []byte) []byte {// Use a closure here to remember state.// Hackish but effective. Depends on Map scanning in order and calling// the closure once per rune.prev := ' 'return Map(func(r rune) rune {if isSeparator(prev) {prev = rreturn unicode.ToTitle(r)}prev = rreturn r},s)
}

作用: 将切片 s 中的所有单词的首字符修改为 Title 格式返回。

 

// TrimLeftFunc treats s as UTF-8-encoded bytes and returns a subslice of s by slicing off
// all leading UTF-8-encoded code points c that satisfy f(c).
func TrimLeftFunc(s []byte, f func(r rune) bool) []byte {i := indexFunc(s, f, false)if i == -1 {return nil}return s[i:]
}

作用:去除切片s中左侧符合f函数的元素

 

// TrimRightFunc returns a subslice of s by slicing off all trailing
// UTF-8-encoded code points c that satisfy f(c).
func TrimRightFunc(s []byte, f func(r rune) bool) []byte {i := lastIndexFunc(s, f, false)if i >= 0 && s[i] >= utf8.RuneSelf {_, wid := utf8.DecodeRune(s[i:])i += wid} else {i++}return s[0:i]
}

作用:去除切片s右侧符合f函数的元素

 

// TrimFunc returns a subslice of s by slicing off all leading and trailing
// UTF-8-encoded code points c that satisfy f(c).
func TrimFunc(s []byte, f func(r rune) bool) []byte {return TrimRightFunc(TrimLeftFunc(s, f), f)
}

作用:去除切片s两侧符合f函数的元素

 

// TrimPrefix returns s without the provided leading prefix string.
// If s doesn't start with prefix, s is returned unchanged.
func TrimPrefix(s, prefix []byte) []byte {if HasPrefix(s, prefix) {return s[len(prefix):]}return s
}

作用:去除切片s前面的prefix切片,如果prefix不是s的头部,则不去除直接返回切片s

 

// TrimSuffix returns s without the provided trailing suffix string.
// If s doesn't end with suffix, s is returned unchanged.
func TrimSuffix(s, suffix []byte) []byte {if HasSuffix(s, suffix) {return s[:len(s)-len(suffix)]}return s
}

作用:去除切片s后缀的suffix,如果suffix不是s的尾部,则不进行去除操作

 

// IndexFunc interprets s as a sequence of UTF-8-encoded code points.
// It returns the byte index in s of the first Unicode
// code point satisfying f(c), or -1 if none do.
func IndexFunc(s []byte, f func(r rune) bool) int {return indexFunc(s, f, true)
}

作用:查找符合 f 的字符在 s 中第一次出现的位置,找不到则返回 -1。

 

// LastIndexFunc interprets s as a sequence of UTF-8-encoded code points.
// It returns the byte index in s of the last Unicode
// code point satisfying f(c), or -1 if none do.
func LastIndexFunc(s []byte, f func(r rune) bool) int {return lastIndexFunc(s, f, true)
}

作用:查找符合 f 的字符在 s 中最后一次出现的位置,找不到则返回 -1。

 

// Trim returns a subslice of s by slicing off all leading and
// trailing UTF-8-encoded code points contained in cutset.
func Trim(s []byte, cutset string) []byte {return TrimFunc(s, makeCutsetFunc(cutset))
}

作用:移除切片s前后两端符合cutset字符串的元素

 

// TrimLeft returns a subslice of s by slicing off all leading
// UTF-8-encoded code points contained in cutset.
func TrimLeft(s []byte, cutset string) []byte {return TrimLeftFunc(s, makeCutsetFunc(cutset))
}

作用:移除切片s左侧符合cutset的元素

 

// TrimRight returns a subslice of s by slicing off all trailing
// UTF-8-encoded code points that are contained in cutset.
func TrimRight(s []byte, cutset string) []byte {return TrimRightFunc(s, makeCutsetFunc(cutset))
}

作用:移除切片s右侧符合cutset字符串的元素

 

// TrimSpace returns a subslice of s by slicing off all leading and
// trailing white space, as defined by Unicode.
func TrimSpace(s []byte) []byte {return TrimFunc(s, unicode.IsSpace)
}

作用:移除切片s中左右两侧的空格

 

// Runes interprets s as a sequence of UTF-8-encoded code points.
// It returns a slice of runes (Unicode code points) equivalent to s.
func Runes(s []byte) []rune {t := make([]rune, utf8.RuneCount(s))i := 0for len(s) > 0 {r, l := utf8.DecodeRune(s)t[i] = ri++s = s[l:]}return t
}

作用:将字节数组安装UTF-8编码转成[]rune切片

 

// Replace returns a copy of the slice s with the first n
// non-overlapping instances of old replaced by new.
// If old is empty, it matches at the beginning of the slice
// and after each UTF-8 sequence, yielding up to k+1 replacements
// for a k-rune slice.
// If n < 0, there is no limit on the number of replacements.
func Replace(s, old, new []byte, n int) []byte {m := 0if n != 0 {// Compute number of replacements.m = Count(s, old)}if m == 0 {// Just return a copy.return append([]byte(nil), s...)}if n < 0 || m < n {n = m}// Apply replacements to buffer.t := make([]byte, len(s)+n*(len(new)-len(old)))w := 0start := 0for i := 0; i < n; i++ {j := startif len(old) == 0 {if i > 0 {_, wid := utf8.DecodeRune(s[start:])j += wid}} else {j += Index(s[start:], old)}w += copy(t[w:], s[start:j])w += copy(t[w:], new)start = j + len(old)}w += copy(t[w:], s[start:])return t[0:w]
}

作用:用new切片替换s切片中old切片元素,n是替换的个数

 

// EqualFold reports whether s and t, interpreted as UTF-8 strings,
// are equal under Unicode case-folding.
func EqualFold(s, t []byte) bool {for len(s) != 0 && len(t) != 0 {// Extract first rune from each.var sr, tr runeif s[0] < utf8.RuneSelf {sr, s = rune(s[0]), s[1:]} else {r, size := utf8.DecodeRune(s)sr, s = r, s[size:]}if t[0] < utf8.RuneSelf {tr, t = rune(t[0]), t[1:]} else {r, size := utf8.DecodeRune(t)tr, t = r, t[size:]}// If they match, keep going; if not, return false.// Easy case.if tr == sr {continue}// Make sr < tr to simplify what follows.if tr < sr {tr, sr = sr, tr}// Fast check for ASCII.if tr < utf8.RuneSelf && 'A' <= sr && sr <= 'Z' {// ASCII, and sr is upper case.  tr must be lower case.if tr == sr+'a'-'A' {continue}return false}// General case. SimpleFold(x) returns the next equivalent rune > x// or wraps around to smaller values.r := unicode.SimpleFold(sr)for r != sr && r < tr {r = unicode.SimpleFold(r)}if r == tr {continue}return false}// One string is empty. Are both?return len(s) == len(t)
}

作用:判断切片s和t是否相等,忽略大小写

 

func IndexByte(s []byte, c byte) int

作用:字节c在切片s中第一次出现的索引,如果不包含在切片s中则返回-1

 

func Equal(a, b []byte) bool

作用:判断两个切片a和b是否想等

 

func Compare(a, b []byte) int

作用:用于两个切片a和b进行比较

a > b 返回1

a < b 返回-1

a == b 返回0

  相关解决方案