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</