Golang bytes源码分析

ByteTracker跟踪代码和原理详解,一看就懂! ByteTracker跟踪器的代码和原理详解 阅读详情

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 int
	na := 0
	for len(s) > 0 {
		if na+1 >= n {
			a[na] = s
			na++
			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 case
	if len(sep) == 0 {
		return utf8.RuneCount(s) + 1
	}
	n := 0
	for {
		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 -1
	case !utf8.ValidRune(r):
		return -1
	default:
		var b [utf8.UTFMax]byte
		n := 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 int
	for 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 -= size
		for _, 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 := 0
	for 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] = s
	return 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 := 0
	wasSpace := 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 |= r
		isSpace := int(asciiSpace[r])
		n += wasSpace & ^isSpace
		wasSpace = isSpace
	}

	if setBits >= utf8.RuneSelf {
		// Some runes in the input slice are not ASCII.
		return FieldsFunc(s, unicode.IsSpace)
	}

	// ASCII fast path
	a := make([][]byte, n)
	na := 0
	fieldStart := 0
	i := 0
	// Skip spaces in the front of the input.
	for i < len(s) && asciiSpace[s[i]] != 0 {
		i++
	}
	fieldStart = i
	for 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 int
		end   int
	}
	spans := make([]span, 0, 32)

	// Find the field start and end indices.
	wasField := false
	fromIndex := 0
	for i := 0; i < len(s); {
		size := 1
		r := 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 = i
				wasField = 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 b
	nbytes := 0        // number of bytes encoded in b
	b := make([]byte, maxbytes)
	for i := 0; i < len(s); {
		wid := 1
		r := 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.UTFMax
				nb := 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 separators
	if r <= 0x7F {
		switch {
		case '0' <= r && r <= '9':
			return false
		case 'a' <= r && r <= 'z':
			return false
		case 'A' <= r && r <= 'Z':
			return false
		case r == '_':
			return false
		}
		return true
	}
	// Letters and digits are not separators
	if 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 = r
				return unicode.ToTitle(r)
			}
			prev = r
			return 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 := 0
	for len(s) > 0 {
		r, l := utf8.DecodeRune(s)
		t[i] = r
		i++
		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 := 0
	if 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 := 0
	start := 0
	for i := 0; i < n; i++ {
		j := start
		if 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 rune
		if 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

string to bytes, bytes to string import "unsafe" func Str2Bytes(s string) []byte { x := (*[2]uintptr)(unsafe.Pointer(&s)) h := [3]uintptr{x[0], x[1], x[1]} return *(*[]byte)(unsafe.Pointer(&h)) } func Bytes2Str(b []byte) string { return *(*string)(unsafe.Pointer(&b)) } 阅读详情

相关推荐

Python,Bytetrack 源码解读,参数,源码解释,逐句分析代码,目标追踪

self.tracked_stracks 中是上一帧的所有【STrack对象】,在这一帧里面,有的被分入unconfirmed中,而unconfirmed中没有匹配高分框的话就会标志被标志移除【见4、处理 unconfirmed 匹配】。所以下面这句话就挑选中上一帧还处于追踪的【STrack对象】。2、低分框和上一帧的【STrack对象List】tracked_stracks匹配成功,以更低松懈阈值匹配,不满足track.state == TrackState.Tracked,重新激活。

q742971636的博客 2366

分享48个Go源码,总有一款适合您

GO

zy0412326的专栏 3774

ByteTrack源码

ByteTrack源码

Bytetrack 环境配置 &核心代码解析

Bytetrack 环境配置 &核心代码解析

weixin_50862344的博客 5092

OMNET++ INET框架学习教程(一)

在自组网学习的道路上摸石头过河,帮你快速入门OIMNET++平台下的INET框架。

NLDwangzhe的博客 6565

Unity基础篇-----Input输入

2、Input.GetTouch()方法,主要用于移动端开发使用,此方法主要获取触摸屏幕的操作数据,首先通过Input.touchCount这个方法获取到手指触摸屏幕的次数,通过GetTouch方法传输触摸次数,调用Touch结构判断手指的状态来是否为设定的状态,符合的话则执行相关内容。参数(“Horizontal”)表示左右的值,值为-1时,表示你在一直按下左方向对应的按键、设备类型为手柄时,表示你把推杆推到了最左边,为0时为默认位置,手柄中对应正中间,为1时与-1时对应的情况正好相反。

why820mmm的博客 3495

深入理解GO语言:GC原理及源码分析

Go 中的runtime 类似 Java的虚拟机,它负责管理包括内存分配、垃圾回收、栈处理、goroutine、channel、切片(slice)、map 和反射(reflection)等。Go 的可执行文件都比相对应的源代码文件要大很多,这是因为 Go 的 runtime 嵌入到了每一个可执行文件当中。 常见的几种gc算法: 引用计数:对每个对象维护一个引用计数,当引用该对象的对象被销毁时,引用计数减1,当引用计数器为0是回收该对象。 优点:对象可以很快的被回收,不会出现内存耗尽或达到某个阀值时才回

cyq6239075的博客 5219

ESP32-CAM实战:从零构建高精度QR二维码识别系统

本文详细介绍了如何使用ESP32-CAM构建高精度QR二维码识别系统,涵盖硬件配置、开发环境搭建、二维码识别库选择与优化、完整系统实现及实战问题排查。通过优化识别算法和电源管理,系统可实现快速、稳定的二维码识别,适用于物联网设备绑定等场景。

weixin_42524703的博客 435

Golang源码分析bytes.go

Golang源码分析bytes.go

gopher123的博客 1128

目标检测之Mask R-CNN(Pytorch):小白动手实现项目

目标检测之Mask R-CNN:小白动手实现项目Pytorch引言Mask R-CNN原理简述代码、注释及详细解释 引言 首先声明本项目的运行环境。操作系统为Windows,编写环境为Anaconda3 + Jupyter Notebook。Pytorch版本为 torch 1.7.1+cu110 、torchvision版本为 0.8.2+cu110,cuda版本为cu100,显卡为Nvidia 2060。 我是目标检测领域的小白,刚刚完成了Pytorch的相关入门学习任务,所以我认为学习本篇博客的基础

dzc_go的博客 1万+

别再只跑recon-all了!FreeSurfer实战:从T1图像到freeview可视化的完整避坑指南

本文详细解析FreeSurfer从T1图像处理到freeview可视化的全流程,包括环境配置、recon-all深度解析、高级可视化技巧及性能优化策略。特别针对常见错误提供解决方案,帮助用户高效完成MRI数据分析,避免常见陷阱。

weixin_33404102的博客 353

Golang源码分析

Golang源码分析 Golang源码分析-builtin.go Golang源码分析-bytes.go Golang源码分析-bytes/buffer.go Golang源码分析-bytes/reader.go Golang源码分析-strings.go Golang源码分析-strings builder.go Golang源码分析-strconv包 Golang源码分析-io.go Golang源码分析-io/pipe.go Golang源码分析-io/ioutil.go Gol

hixiaoyang的博客 793

ROS Noetic + Realsense ROS 2.3.2 在鲁班猫4上的完整工作空间搭建与相机启动调试

本文详细介绍了在鲁班猫4(RK3588S)开发板上搭建ROS Noetic与Realsense ROS 2.3.2开发环境的完整流程,包括Realsense SDK安装、工作空间配置、D435i深度相机驱动调试等关键步骤,为机器人视觉系统开发提供实用指南。

weixin_33217202的博客 238

Golang bytes.Buffer源码分析

Golang bytes.Buffer分析 Buffer作为高效缓存支持读、写与撤销读取操作,可用于字节流缓存与解析等。这里简要分析一下其源码实现。 本文源码版本为go1.16.3 linux/amd64 自增长规则 Buffer可以在长度不足时增加自身长度,其核心增长函数是grow(n int) int私有函数,源码在go/src/bytes/buffer.go第117行: // grow grows the buffer to guarantee space for n more bytes. //

QixuanAIRobot的专栏 664

论文分栏前后内容不连续?教你word如何删除分节符

问题 当我们在写论文的时候,很多期刊的模板都是两栏的格式,但有的时候我们插入的图像尺寸可能太大,两栏格式放不下,因此需要将其以一栏的格式出入,如下: 但当我们把图片删除后,再将其转换成两栏格式,前后内容就出现不连续的情况: 正常情况下应该是如下: 正确处理方式 里面有个分页符,把分页符去掉,或者把你的文字全部复制到记事本里,然后重新复制回word就可以取消原有的格式了。 删除分节符的方法(以word 2019为例) -点击菜单栏上的“视图”,点击“大纲视图”。 可以看到word文档以整列的形式展开:

左手の明天的博客 1万+

从养虾到退坑:OpenClaw 卸载不留残留,一步到位

文章摘要: 本文提供OpenClaw软件的完整卸载指南,适用于Windows、macOS和Linux系统。内容包含卸载前的数据备份步骤(配置文件、日志、插件列表),以及详细的卸载脚本。Windows版通过批处理文件删除程序文件、注册表项和环境变量;macOS/Linux版则提供shell脚本,涵盖服务停止、软件包卸载、配置清理等步骤。特别强调要删除所有用户数据(包括多用户环境),确保系统无残留。文末建议重启计算机以使更改生效,实现"一步到位"的彻底卸载。

一键难忘的博客 298

Golang bytes包Buffer源码分析

bytes/buffer.go Buffer提供了一个可扩展的字节缓冲区,底层是对[]byte进行封装,提供读写的功能。 结构体 type Buffer struct { buf []byte // contents are the bytes buf[off : len(buf)] 缓冲区 off int // read at &buf[off], write at &buf[len(buf)] 读写的索引值,指针偏移量 .

skh2015java的博客 1103

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

golang bytes数组转io.writer_Rust并发:bytes源码分析

bytes库Rust网络编程中使用比较频繁,其提供了和字节数组相关的一组抽象,能够极大避免内存拷贝。提供的主要组件如下:Bytes结构: 底层封装了一段连续的内存,提供了引用计数跟踪内存的生命周期,类似 &'static [u8],可供多个实例共享。Buf/BufMut trait: 对逻辑上连续,但是底层表示可能不连续的Buffer抽象,分别类似 &[&[u8]]和 &a...

weixin_33504929的博客 508

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

一文学会Golang里拼接字符串的6种方式(性能对比)

本文详细比较了Go语言中不同字符串拼接方式,包括基本运算符+、fmt.Sprintf、strings.Join、strings.Builder、bytes.Buffer以及使用[]byte的性能。实验结果显示strings.Builder和bytes.Buffer在效率上有显著优势。

LightOfNight的博客 2607

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

grpc-go源码剖析四十六之服务器端是如何将数据帧缓存到recvBuffer里?(多个数据帧时,在底层是如何来存储的?)

经过前面几篇文章分析,我们已经服务器端接收到数据帧后,经历抽样流控,链路流控,流级别流控; 那么,接下来我们要考虑的问题是,服务器端如何来维护接收到数据帧呢? 换句话说,服务器端接收到不止一个数据帧时,按照什么原则来存储这些数据帧? 是随意存储,还是存储到单链表里呢? 1、数据帧存储到recvBuffer里的整体流程图? 1.1、存储模型图? 数据帧在grpc框架中的存储是利用channel+bytes.Buffer作为底层存储的(recvBuffer.c + recvBuffer.backlog)。

码二哥的技术池 598

十二. go 高性能编程之 sync.Pool的复用对象

【代码】十二. go 高性能编程之 sync.Pool的复用对象。

qq_29799655的博客 732

【终于明白了】源码+图解分析梳理 Golang 中输入输出I/O

文章目录前言标准库的区别1. 提供基本接口的`io`最基础的接口 `io.Reader`与`io.Writer`辅助接口 `io.Seeker`与`io.Closer`进阶:偏移量指定`io.ReaderAt`和`io.WriterAt`进阶:来源与去处指定 `io.ReaderFrom`和 `io.WiterTo`适配:各种数据类型的读取与写入Byte 读写一个字节Rune 读一个字符String 写入一个字符串组合:各式各样的接口搭配总结:io库中的所有接口概要图实现:接口的各种实现场景附:io库中的一

weixin_38371073的博客 951

golang 之bytes.Buffer 写操作扩容解读

golang(go1.12.9) 的标准包bytes.Buffer,是一个简单的字节(byte) 缓冲buffer, 定义了一个默认的最小容量smallBufferSize = 64,实现了byte的读,写,清空等操作, 其中写操作稍微麻烦,需要考虑扩容的情形,下面主要分析一下buffer 扩容 首先,看一下buffer结构体的定义 type Buffer struct { buf [...

西格玛的博客 2731

Go 语言 bytes.Buffer 源码详解 2

Go 语言中的 bytes.Buffer 是大小可变的字节缓冲区,本篇文章,我们对 Buffer 结构源码进行了逐行分析,了解了底层读写方法的实现原理,并简单介绍了使用方法。

u012948302的专栏 733

go字符串拼接方式及性能比拼

在golang中字符串的拼接方式有多种,本文将会介绍比较常用的几种方式,并且对各种方式进行压测,以此来得到在不同场景下更适合使用的方案。

Peerless__的博客 3167
上一篇: Golang bufio包Scanner源码
下一篇: Golang bytes包Buffer源码分析
思维的深度
博客等级 码龄11年 2万+粉丝 391原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值