strings包和bytes包 strings
包和bytes
包非常像,几乎所有函数都有string
和[]byte
两种接口,其中前者被实现在strings
包中,而后者被是现在bytes
包中,所以这里将这两个包一起学习。
官方文档:
strings包:https://pkg.go.dev/[email protected]
bytes包:https://pkg.go.dev/[email protected]
每篇一首歌
函数 clone 1 2 3 4 func Clone (s string ) string func Clone (b []byte ) []byte
克隆[]byte和string。默认赋值操作只是浅拷贝,Clone会对[]byte和string进行深拷贝。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 func CloneTest () { sliceCopyTest() sliceCloneTest() stringCopyTest() stringCloneTest() } func sliceCopyTest () { bts01 := []byte ("testing" ) bts02 := bts01 fmt.Print("Copy(bts02 := bts01), " ) bts01[0 ] = 's' fmt.Println("bts01[0] = 's':" ) fmt.Printf("bts01 = %q, bts02 = %q\n" , bts01, bts02) fmt.Println() } func sliceCloneTest () { bts01 := []byte ("testing" ) bts02 := bytes.Clone(bts01) fmt.Print("Copy(bts02 := bytes.Clone(bts01)), " ) bts01[0 ] = 's' fmt.Println("bts01[0] = 's':" ) fmt.Printf("bts01 = %q, bts02 = %q\n" , bts01, bts02) fmt.Println() } func stringCopyTest () { str01 := "testing" str02 := str01 fmt.Println("str02 := str01:" ) fmt.Printf("unsafe.StringData(str01) == unsafe.StringData(str02): %v\n" , unsafe.StringData(str01) == unsafe.StringData(str02)) fmt.Println() } func stringCloneTest () { str01 := "testing" str02 := strings.Clone(str01) fmt.Println("str02 := strings(str01):" ) fmt.Printf("unsafe.StringData(str01) == unsafe.StringData(str02): %v\n" , unsafe.StringData(str01) == unsafe.StringData(str02)) fmt.Println() }
内容检查类的函数,是否包含。Contains/Has. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 func Contains (s, substr string ) bool func ContainsRune (s string , r rune ) bool func ContainsAny (s, chars string ) bool func ContainsFunc (s string , f func (rune ) bool ) bool func HasPrefix (s, prefix string ) bool func HasSuffix (s, suffix string ) bool func Contains (b, subslice []byte ) bool func ContainsRune (b []byte , r rune ) bool func ContainsAny (b []byte , chars string ) bool func ContainsFunc (b []byte , f func (rune ) bool ) bool func HasPrefix (s, prefix []byte ) bool func HasSuffix (s, suffix []byte ) bool
测试:
1 2 3 4 5 6 7 8 9 10 func ContainsAndHasTest () { str01 := "“你好”是一个很好的词汇" fmt.Println(strings.Contains(str01, "词汇" )) fmt.Println(strings.ContainsAny(str01, "词语" )) fmt.Println(strings.ContainsRune(str01, '你' )) fmt.Println(strings.ContainsFunc(str01, func (r rune ) bool { return r == '你' || r == '我' })) fmt.Println(strings.HasPrefix(str01, "“你好" )) fmt.Println(strings.HasSuffix(str01, "词汇" )) fmt.Println() }
Count 1 2 3 4 func Count (s, substr string ) int func Count (s, sep []byte ) int
获取字串在s中的数量,字串为空串则返回1 + s中unicode码点的数量
获取字串的下标 Index 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 func Index (s, substr string ) int func IndexRune (s string , r rune ) int func IndexByte (s string , c byte ) int func IndexAny (s, chars string ) int func IndexFunc (s string , f func (rune ) bool ) int func LastIndex (s, substr string ) int func LastIndexAny (s, chars string ) int func LastIndexByte (s string , c byte ) int func LastIndexFunc (s string , f func (rune ) bool ) int func Index (s, sep []byte ) int func IndexAny (s []byte , chars string ) int func IndexByte (b []byte , c byte ) int func IndexFunc (s []byte , f func (r rune ) bool ) int func IndexRune (s []byte , r rune ) int func LastIndex (s, sep []byte ) int func LastIndexAny (s []byte , chars string ) int func LastIndexByte (s []byte , c byte ) int func LastIndexFunc (s []byte , f func (r rune ) bool ) int
获取string/[]byte中rune/byte/string/[]byte的下标/最后一个下标的函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 func IndexTest () { str01 := "你好你好你呀" str02 := "好你" fmt.Printf("Index(%q, %q) = %d\n" , str01, str02, strings.Index(str01, str02)) fmt.Printf("IndexByte(%q, %q) = %d\n" , str01, str02[0 ], strings.IndexByte(str01, str02[0 ])) r, _ := utf8.DecodeRuneInString(str02) fmt.Printf("IndexRune(%q, %q) = %d\n" , str01, r, strings.IndexRune(str01, r)) fmt.Printf("IndexAny(%q, %q) = %d\n" , str01, str02, strings.IndexAny(str01, str02)) isNi := func (r rune ) bool { return r == '你' } fmt.Printf("IndexFunc(%q, isNi) = %d\n" , str01, strings.IndexFunc(str01, isNi)) fmt.Printf("LastIndex(%q, %q) = %d\n" , str01, str02, strings.LastIndex(str01, str02)) fmt.Printf("LastIndexByte(%q, %q) = %d\n" , str01, str02[0 ], strings.LastIndexByte(str01, str02[0 ])) fmt.Printf("LastIndexAny(%q, %q) = %d\n" , str01, str02, strings.LastIndexAny(str01, str02)) fmt.Printf("LastIndexFunc(%q, isNi) = %d\n" , str01, strings.LastIndexFunc(str01, isNi)) }
相等性测试 1 2 3 4 5 6 7 8 9 func EqualFold (s, t string ) bool func Equal (a, b []byte ) bool func EqualFold (s, t []byte ) bool
Equal是相等性测试,EqualFold是忽略大小写的相等性测试。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 func Equal [T comparable ](a, b []T) bool { if len (a) != len (b) { return false } for i := 0 ; i < len (a); i++ { if a[i] != b[i] { return false } } return true } func EqualTest () { strSlice := []string {"abc" , "def" , "你好" } strSlice2 := []string {"abc" , "def" , "你好" } byteSlice := []byte {1 , 2 , 3 , 4 , 5 } byteSlice2 := []byte {1 , 2 , 3 , 4 , 5 } fmt.Printf("Equal(%q, %q) = %v\n" , strSlice, strSlice2, Equal(strSlice, strSlice2)) fmt.Printf("Equal(%q, %q) = %v\n" , byteSlice, byteSlice2, Equal(byteSlice, byteSlice2)) }
去掉前缀、后缀,分割等函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 func Cut (s, sep string ) (before, after string , found bool )func CutPrefix (s, prefix string ) (after string , found bool )func CutSuffix (s, suffix string ) (before string , found bool )func Split (s, sep string ) []string func SplitN (s, sep string , n int ) []string func SplitAfter (s, sep string ) []string func SplitAfterN (s, sep string , n int ) []string func Fields (s string ) []string func FieldsFunc (s string , f func (rune ) bool ) []string func Trim (s, cutset string ) string func TrimSpace (s string ) string func TrimFunc (s string , f func (rune ) bool ) string func TrimLeft (s, cutset string ) string func TrimRight (s, cutset string ) string func TrimLeftFunc (s string , f func (rune ) bool ) string func TrimRightFunc (s string , f func (rune ) bool ) string func TrimPrefix (s, prefix string ) string func TrimSuffix (s, suffix string ) string func Cut (s, sep []byte ) (before, after []byte , found bool )func CutPrefix (s, prefix []byte ) (after []byte , found bool )func CutSuffix (s, suffix []byte ) (before []byte , found bool )func Split (s, sep []byte ) [][]byte func SplitAfter (s, sep []byte ) [][]byte func SplitAfterN (s, sep []byte , n int ) [][]byte func SplitN (s, sep []byte , n int ) [][]byte func Fields (s []byte ) [][]byte func FieldsFunc (s []byte , f func (rune ) bool ) [][]byte func Trim (s []byte , cutset string ) []byte func TrimFunc (s []byte , f func (r rune ) bool ) []byte func TrimLeft (s []byte , cutset string ) []byte func TrimLeftFunc (s []byte , f func (r rune ) bool ) []byte func TrimPrefix (s, prefix []byte ) []byte func TrimRight (s []byte , cutset string ) []byte func TrimRightFunc (s []byte , f func (r rune ) bool ) []byte func TrimSpace (s []byte ) []byte func TrimSuffix (s, suffix []byte ) []byte
重复字符串 1 2 3 4 5 6 func Repeat (s string , count int ) string func Repeat (b []byte , count int ) []byte
单纯的将s重复几次
替换字符串/转换字符串 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 func Map (mapping func (rune ) rune , s string ) string func Replace (s, old, new string , n int ) string func ReplaceAll (s, old, new string ) string func ToLower (s string ) string func ToLowerSpecial (c unicode.SpecialCase, s string ) string func ToTitle (s string ) string func ToTitleSpecial (c unicode.SpecialCase, s string ) string func ToUpper (s string ) string func ToUpperSpecial (c unicode.SpecialCase, s string ) string func ToValidUTF8 (s, replacement string ) string func Map (mapping func (r rune ) rune , s []byte ) []byte func Replace (s, old, new []byte , n int ) []byte func ReplaceAll (s, old, new []byte ) []byte func Runes (s []byte ) []rune func ToLower (s []byte ) []byte func ToLowerSpecial (c unicode.SpecialCase, s []byte ) []byte func ToTitle (s []byte ) []byte func ToTitleSpecial (c unicode.SpecialCase, s []byte ) []byte func ToUpper (s []byte ) []byte func ToUpperSpecial (c unicode.SpecialCase, s []byte ) []byte func ToValidUTF8 (s, replacement []byte ) []byte
这部分是关于字符串/[]byte的替换/转换的函数,针对的都是字符串,针对单个unicode码点(rune类型)的操作(比如IsUpper, IsSpace, ToUpper)在unicode
库中。
类型(type) 用于构建string的类 因为string是不可变类型,在用+操作符构建string时每一次都要分配一次内存,导致效率低下。
所以go标准库提供了高效构建string的类。
Builder类 1 2 3 4 type Builder struct { }
Builder类型是strings包提供的,用于高效构建string的类,其会最小化内存拷贝。
不要拷贝非零的Builder对象。
Builder类的成员方法 1 func (b *Builder) Len() int
builder已经写入的字节数;b.Len() = len(b.String())
1 func (b *Builder) Cap() int
获取该builder已经分配的,用于构建string的空间,包括已经写入的空间。
1 func (b *Builder) Grow(n int )
增长builder的容量,使其至少能再写入n个字节,而不用再次分配内存。
1 func (b *Builder) Reset()
清空builder已经写入的内容
1 func (b *Builder) String() string
返回累加的string
1 2 3 4 func (b *Builder) Write(p []byte ) (int , error )func (b *Builder) WriteByte(c byte ) error func (b *Builder) WriteRune(r rune ) (int , error )func (b *Builder) WriteString(s string ) (int , error )
向builder中写入内容。
Buffer类 1 2 3 type Buffer struct { }
Buffer是bytes包提供的高效的string构建类,其比Builder更加强大。Builder的读出操作只有String()方法,Buffer支持更多的读出方法。
与Buffer类相关的函数 1 2 func NewBuffer (buf []byte ) *Bufferfunc NewBufferString (s string ) *Buffer
分别以[]byte和string的内容为基础构建新的Buffer类实例。
大多数情况下,new(Buffer)
(或者直接定义一个Buffer类型的变脸)就可以初始化一个空的Buffer。
Buffer类的成员方法 1 2 3 func (b *Buffer) Available() int func (b *Buffer) Cap() int func (b *Buffer) Len() int
空间大小相关的函数。Cap()
返回Buffer的内部空间的容量。Available()
返回还未使用的,但已经申请的空间的大小。Len()
返回写入后未读出的空间的大小。
1 func (b *Buffer) Grow(n int )
使得Buffer至少能再读入n个字节而不重新分配内存。
1 func (b *Buffer) Truncate(n int )
除了前n个未读的字节外,丢弃其他已写入的字节,不会重新分配内存。
1 2 3 4 5 func (b *Buffer) ReadFrom(r io.Reader) (n int64 , err error )func (b *Buffer) Write(p []byte ) (n int , err error )func (b *Buffer) WriteByte(c byte ) error func (b *Buffer) WriteRune(r rune ) (n int , err error )func (b *Buffer) WriteString(s string ) (n int , err error )
向Buffer中写入内容。
与strings.Builder
不同的是有一个ReadFrom()
方法,该方法从一个io.Reader
(这是一个接口,包含Read()
方法)中读取内容,并返回读取的字节数量和出现的错误(io.EOF
不视为错误,io.Reader
的Read()
方法返回io.EOF
时ReadFrom()
方法不会返回错误)。
1 2 3 4 5 6 7 8 func (b *Buffer) Bytes() []byte func (b *Buffer) Read(p []byte ) (n int , err error )func (b *Buffer) ReadByte() (byte , error )func (b *Buffer) ReadBytes(delim byte ) (line []byte , err error )func (b *Buffer) ReadRune() (r rune , size int , err error )func (b *Buffer) ReadString(delim byte ) (line string , err error )func (b *Buffer) String() string func (b *Buffer) WriteTo(w io.Writer) (n int64 , err error )
Buffer类中有众多的读出方式,包括读取全部字节、读指定数量的字节、读一个字节、读到某个字节为止、读一个unicode码点、全部都出来作为一个string
。
同时Buffer类还有一个与ReadFrom()
对应的方法WriteTo()
,该方法将字节写入到一个io.Writer
(这是一个接口,包含Write()
方法)中,并返回写入的字节数和出现的错误。
1 func (b *Buffer) AvailableBuffer() []byte
返回未写入的空闲的空间,直到下次写入操作前该空间都有效。
1 2 func (b *Buffer) UnreadByte() error func (b *Buffer) UnreadRune() error
将上次读取的byte/rune回退到缓冲区中。
用于读取string/[]byte的类 有时候我们需要将string
/[]byte
当作输入,strings和bytes包中都提供了名为Reader
的类,用于将string
/[]byte
作为输入源。
strings.Reader 1 2 3 type Reader struct { }
实现了io.Reader, io.ReaderAt, io.ByteReader, io.ByteScanner, io.RuneReader, io.RuneScanner, io.Seeker, io.WriterTo
接口,使用string
作为输入源,零值的行为与以空字符串初始化相同。
strings.Reader相关函数 1 func NewReader (s string ) *Reader
以s
为输入源创建一个strings.Reader
。
成员函数 1 2 3 4 5 6 7 8 9 10 11 func (r *Reader) Len() int func (r *Reader) Read(b []byte ) (n int , err error )func (r *Reader) ReadAt(b []byte , off int64 ) (n int , err error )func (r *Reader) ReadByte() (byte , error )func (r *Reader) ReadRune() (ch rune , size int , err error )func (r *Reader) Reset(s string ) func (r *Reader) Seek(offset int64 , whence int ) (int64 , error ) func (r *Reader) Size() int64 func (r *Reader) UnreadByte() error func (r *Reader) UnreadRune() error func (r *Reader) WriteTo(w io.Writer) (n int64 , err error )
大部分语义和前面的一样,没见过的加了注释。
bytes.Reader 1 2 3 type Reader struct { }
和strings.Reader
类似,只不过使用[]byte
作为输入源。
相关函数 1 func NewReader (b []byte ) *Reader
成员函数 1 2 3 4 5 6 7 8 9 10 11 func (r *Reader) Len() int func (r *Reader) Read(b []byte ) (n int , err error )func (r *Reader) ReadAt(b []byte , off int64 ) (n int , err error )func (r *Reader) ReadByte() (byte , error )func (r *Reader) ReadRune() (ch rune , size int , err error )func (r *Reader) Reset(b []byte )func (r *Reader) Seek(offset int64 , whence int ) (int64 , error )func (r *Reader) Size() int64 func (r *Reader) UnreadByte() error func (r *Reader) UnreadRune() error func (r *Reader) WriteTo(w io.Writer) (n int64 , err error )
strings.Replacer 1 2 3 type Replacer struct { }
用于方便地替换string中的内容的辅助类,看后面的例子就明白了。
相关函数 1 func NewReplacer (oldnew ...string ) *Replacer
以old1, new1, old2, new2…的顺序构建Replacer,表示将后续的字符串中的所有的old1/old2/…替换为new1/new2/…
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package mainimport ( "fmt" "strings" ) func main () { r := strings.NewReplacer("<" , "<" , ">" , ">" ) fmt.Println(r.Replace("This is <b>HTML</b>!" )) }
成员函数 1 func (r *Replacer) Replace(s string ) string
将s
按照预定义的规则替换,返回替换后的字符串。
1 func (r *Replacer) WriteString(w io.Writer, s string ) (n int , err error )
将替换后的字符串写入w