package bytes

import "bytes"

Package bytes 实现了用于操作字节切片的函数。 它的功能与 strings 包的工具类似。

Index

Examples

Constants

const MinRead = 512

MinRead 是 Buffer.ReadFrom 调用 Buffer.Read 时传入的最小切片大小。 只要缓冲区在容纳 r 的内容后仍有至少 MinRead 字节的剩余空间, Buffer.ReadFrom 就不会扩容底层缓冲区。

Variables

var ErrTooLarge = errors.New("bytes.Buffer: too large")

若无法分配内存存储缓冲区数据,会触发 panic 并传入 ErrTooLarge。

Functions

func Clone

func Clone(b []byte) []byte

Clone 返回 b[:len(b)] 的副本。 结果可能包含额外未使用的容量。 Clone(nil) 返回 nil。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	b := []byte("abc")
	clone := bytes.Clone(b)
	fmt.Printf("%s\n", clone)
	clone[0] = 'd'
	fmt.Printf("%s\n", b)
	fmt.Printf("%s\n", clone)
}

Output:

abc
abc
dbc

func Compare

func Compare(a, b []byte) int

Compare 按字典序比较两个字节切片并返回一个整数。 若 a == b,结果为 0;若 a < b,结果为 -1;若 a > b,结果为 +1。 nil 参数等价于空切片。

Example
package main

import (
	"bytes"
)

func main() {
	// Interpret Compare's result by comparing it to zero.
	var a, b []byte
	if bytes.Compare(a, b) < 0 {
		// a less b
	}
	if bytes.Compare(a, b) <= 0 {
		// a less or equal b
	}
	if bytes.Compare(a, b) > 0 {
		// a greater b
	}
	if bytes.Compare(a, b) >= 0 {
		// a greater or equal b
	}

	// Prefer Equal to Compare for equality comparisons.
	if bytes.Equal(a, b) {
		// a equal b
	}
	if !bytes.Equal(a, b) {
		// a not equal b
	}
}

func Contains

func Contains(b, subslice []byte) bool

Contains 判断子切片 subslice 是否存在于 b 中。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Println(bytes.Contains([]byte("seafood"), []byte("foo")))
	fmt.Println(bytes.Contains([]byte("seafood"), []byte("bar")))
	fmt.Println(bytes.Contains([]byte("seafood"), []byte("")))
	fmt.Println(bytes.Contains([]byte(""), []byte("")))
}

Output:

true
false
true
true

func ContainsAny

func ContainsAny(b []byte, chars string) bool

ContainsAny 判断 chars 中任意 UTF-8 编码的码点是否存在于 b 中。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Println(bytes.ContainsAny([]byte("I like seafood."), "fÄo!"))
	fmt.Println(bytes.ContainsAny([]byte("I like seafood."), "去是伟大的."))
	fmt.Println(bytes.ContainsAny([]byte("I like seafood."), ""))
	fmt.Println(bytes.ContainsAny([]byte(""), ""))
}

Output:

true
true
false
false

func ContainsFunc

func ContainsFunc(b []byte, f func(rune) bool) bool

ContainsFunc 判断 b 中任意 UTF-8 编码码点 r 是否满足 f(r)。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	f := func(r rune) bool {
		return r >= 'a' && r <= 'z'
	}
	fmt.Println(bytes.ContainsFunc([]byte("HELLO"), f))
	fmt.Println(bytes.ContainsFunc([]byte("World"), f))
}

Output:

false
true

func ContainsRune

func ContainsRune(b []byte, r rune) bool

ContainsRune 判断字符 r 是否包含在 UTF-8 编码的字节切片 b 中。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Println(bytes.ContainsRune([]byte("I like seafood."), 'f'))
	fmt.Println(bytes.ContainsRune([]byte("I like seafood."), 'ö'))
	fmt.Println(bytes.ContainsRune([]byte("去是伟大的!"), '大'))
	fmt.Println(bytes.ContainsRune([]byte("去是伟大的!"), '!'))
	fmt.Println(bytes.ContainsRune([]byte(""), '@'))
}

Output:

true
false
true
true
false

func Count

func Count(s, sep []byte) int

Count 统计 sep 在 s 中非重叠出现的次数。 若 sep 为空切片,Count 返回 1 + s 中 UTF-8 编码码点的数量。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Println(bytes.Count([]byte("cheese"), []byte("e")))
	fmt.Println(bytes.Count([]byte("five"), []byte(""))) // before & after each rune
}

Output:

3
5

func Cut

func Cut(s, sep []byte) (before, after []byte, found bool)

Cut 围绕 sep 的第一个实例分割 s, 返回 sep 前后的文本。found 结果表示 sep 是否出现在 s 中。 若 s 中无 sep,Cut 返回 s、nil、false。

Cut 返回原切片 s 的子切片,非副本。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	show := func(s, sep string) {
		before, after, found := bytes.Cut([]byte(s), []byte(sep))
		fmt.Printf("Cut(%q, %q) = %q, %q, %v\n", s, sep, before, after, found)
	}
	show("Gopher", "Go")
	show("Gopher", "ph")
	show("Gopher", "er")
	show("Gopher", "Badger")
}

Output:

Cut("Gopher", "Go") = "", "pher", true
Cut("Gopher", "ph") = "Go", "er", true
Cut("Gopher", "er") = "Goph", "", true
Cut("Gopher", "Badger") = "Gopher", "", false

func CutPrefix

func CutPrefix(s, prefix []byte) (after []byte, found bool)

CutPrefix 返回移除前导前缀字节切片后的 s, 并报告是否找到前缀。 若 s 不以 prefix 开头,CutPrefix 返回 s、false。 若 prefix 为空字节切片,CutPrefix 返回 s、true。

CutPrefix 返回原切片 s 的子切片,非副本。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	show := func(s, prefix string) {
		after, found := bytes.CutPrefix([]byte(s), []byte(prefix))
		fmt.Printf("CutPrefix(%q, %q) = %q, %v\n", s, prefix, after, found)
	}
	show("Gopher", "Go")
	show("Gopher", "ph")
}

Output:

CutPrefix("Gopher", "Go") = "pher", true
CutPrefix("Gopher", "ph") = "Gopher", false

func CutSuffix

func CutSuffix(s, suffix []byte) (before []byte, found bool)

CutSuffix 返回移除尾部后缀字节切片后的 s, 并报告是否找到后缀。 若 s 不以 suffix 结尾,CutSuffix 返回 s、false。 若 suffix 为空字节切片,CutSuffix 返回 s、true。

CutSuffix 返回原切片 s 的子切片,非副本。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	show := func(s, suffix string) {
		before, found := bytes.CutSuffix([]byte(s), []byte(suffix))
		fmt.Printf("CutSuffix(%q, %q) = %q, %v\n", s, suffix, before, found)
	}
	show("Gopher", "Go")
	show("Gopher", "er")
}

Output:

CutSuffix("Gopher", "Go") = "Gopher", false
CutSuffix("Gopher", "er") = "Goph", true

func Equal

func Equal(a, b []byte) bool

Equal 判断 a 和 b 是否长度相同且包含的字节完全一致。 nil 参数等价于空切片。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Println(bytes.Equal([]byte("Go"), []byte("Go")))
	fmt.Println(bytes.Equal([]byte("Go"), []byte("C++")))
}

Output:

true
false

func EqualFold

func EqualFold(s, t []byte) bool

EqualFold 判断解析为 UTF-8 字符串的 s 和 t, 在简单 Unicode 大小写折叠规则下是否相等(更通用的不区分大小写比较)。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Println(bytes.EqualFold([]byte("Go"), []byte("go")))
}

Output:

true

func Fields

func Fields(s []byte) [][]byte

Fields 将 s 解析为 UTF-8 编码的码点序列。 它以一个或多个连续空白字符(由 unicode.IsSpace 定义)为分隔分割切片 s, 返回 s 的子切片切片;若 s 仅包含空白字符则返回空切片。 返回切片的每个元素均非空。与 Split 不同,首尾的连续空白字符会被舍弃。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Printf("Fields are: %q", bytes.Fields([]byte("  foo bar  baz   ")))
}

Output:

Fields are: ["foo" "bar" "baz"]

func FieldsFunc

func FieldsFunc(s []byte, f func(rune) bool) [][]byte

FieldsFunc 将 s 解析为 UTF-8 编码的码点序列。 它以满足 f(c) 的连续码点为分隔分割切片 s, 返回 s 的子切片切片。若 s 中所有码点都满足 f(c) 或 len(s) == 0,返回空切片。 返回切片的每个元素均非空。与 Split 不同,首尾满足 f(c) 的连续码点会被舍弃。

FieldsFunc 不保证调用 f(c) 的顺序, 并假定对于给定的 c,f 始终返回相同的值。

Example
package main

import (
	"bytes"
	"fmt"
	"unicode"
)

func main() {
	f := func(c rune) bool {
		return !unicode.IsLetter(c) && !unicode.IsNumber(c)
	}
	fmt.Printf("Fields are: %q", bytes.FieldsFunc([]byte("  foo1;bar2,baz3..."), f))
}

Output:

Fields are: ["foo1" "bar2" "baz3"]

func FieldsFuncSeq

func FieldsFuncSeq(s []byte, f func(rune) bool) iter.Seq[[]byte]

FieldsFuncSeq 返回 s 中围绕连续满足 f(c) 的 Unicode 码点分割的子切片的迭代器。 迭代器产生的子切片与 FieldsFunc 但不会构建一个包含这些子切片的新切片。

Example
package main

import (
	"bytes"
	"fmt"
	"unicode"
)

func main() {
	text := []byte("The quick brown fox")
	fmt.Println("Split on whitespace(similar to FieldsSeq):")
	for word := range bytes.FieldsFuncSeq(text, unicode.IsSpace) {
		fmt.Printf("%q\n", word)
	}

	mixedText := []byte("abc123def456ghi")
	fmt.Println("\nSplit on digits:")
	for word := range bytes.FieldsFuncSeq(mixedText, unicode.IsDigit) {
		fmt.Printf("%q\n", word)
	}

}

Output:

Split on whitespace(similar to FieldsSeq):
"The"
"quick"
"brown"
"fox"

Split on digits:
"abc"
"def"
"ghi"

func FieldsSeq

func FieldsSeq(s []byte) iter.Seq[[]byte]

FieldsSeq 返回 s 中围绕连续空白字符(由 unicode.IsSpace 定义)分割的子切片的迭代器。 迭代器产生的子切片与 Fields 但不会构建一个包含这些子切片的新切片。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	text := []byte("The quick brown fox")
	fmt.Println("Split byte slice into fields:")
	for word := range bytes.FieldsSeq(text) {
		fmt.Printf("%q\n", word)
	}

	textWithSpaces := []byte("  lots   of   spaces  ")
	fmt.Println("\nSplit byte slice with multiple spaces:")
	for word := range bytes.FieldsSeq(textWithSpaces) {
		fmt.Printf("%q\n", word)
	}

}

Output:

Split byte slice into fields:
"The"
"quick"
"brown"
"fox"

Split byte slice with multiple spaces:
"lots"
"of"
"spaces"

func HasPrefix

func HasPrefix(s, prefix []byte) bool

HasPrefix 判断字节切片 s 是否以 prefix 开头。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Println(bytes.HasPrefix([]byte("Gopher"), []byte("Go")))
	fmt.Println(bytes.HasPrefix([]byte("Gopher"), []byte("C")))
	fmt.Println(bytes.HasPrefix([]byte("Gopher"), []byte("")))
}

Output:

true
false
true

func HasSuffix

func HasSuffix(s, suffix []byte) bool

HasSuffix 判断字节切片 s 是否以 suffix 结尾。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Println(bytes.HasSuffix([]byte("Amigo"), []byte("go")))
	fmt.Println(bytes.HasSuffix([]byte("Amigo"), []byte("O")))
	fmt.Println(bytes.HasSuffix([]byte("Amigo"), []byte("Ami")))
	fmt.Println(bytes.HasSuffix([]byte("Amigo"), []byte("")))
}

Output:

true
false
false
true

func Index

func Index(s, sep []byte) int

Index 返回 sep 在 s 中首次出现的索引,若 s 中不存在 sep 则返回 -1。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Println(bytes.Index([]byte("chicken"), []byte("ken")))
	fmt.Println(bytes.Index([]byte("chicken"), []byte("dmr")))
}

Output:

4
-1

func IndexAny

func IndexAny(s []byte, chars string) int

IndexAny 将 s 解析为 UTF-8 编码的 Unicode 码点序列。 它返回 chars 中任意 Unicode 码点在 s 中首次出现的字节索引。 若 chars 为空或无共同码点则返回 -1。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Println(bytes.IndexAny([]byte("chicken"), "aeiouy"))
	fmt.Println(bytes.IndexAny([]byte("crwth"), "aeiouy"))
}

Output:

2
-1

func IndexByte

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

IndexByte 返回 c 在 b 中首次出现的索引,若 b 中不存在 c 则返回 -1。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Println(bytes.IndexByte([]byte("chicken"), byte('k')))
	fmt.Println(bytes.IndexByte([]byte("chicken"), byte('g')))
}

Output:

4
-1

func IndexFunc

func IndexFunc(s []byte, f func(r rune) bool) int

IndexFunc 将 s 解析为 UTF-8 编码的码点序列。 它返回 s 中第一个满足 f(c) 的 Unicode 码点的字节索引,若无则返回 -1。

Example
package main

import (
	"bytes"
	"fmt"
	"unicode"
)

func main() {
	f := func(c rune) bool {
		return unicode.Is(unicode.Han, c)
	}
	fmt.Println(bytes.IndexFunc([]byte("Hello, 世界"), f))
	fmt.Println(bytes.IndexFunc([]byte("Hello, world"), f))
}

Output:

7
-1

func IndexRune

func IndexRune(s []byte, r rune) int

IndexRune 将 s 解析为 UTF-8 编码的码点序列。 它返回指定字符在 s 中首次出现的字节索引。 若 s 中不存在该字符则返回 -1。 若 r 为 utf8.RuneError,则返回任意无效 UTF-8 字节序列的首次出现位置。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Println(bytes.IndexRune([]byte("chicken"), 'k'))
	fmt.Println(bytes.IndexRune([]byte("chicken"), 'd'))
}

Output:

4
-1

func Join

func Join(s [][]byte, sep []byte) []byte

Join 拼接 s 中的元素创建新的字节切片。分隔符 sep 会放置在结果切片的元素之间。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	s := [][]byte{[]byte("foo"), []byte("bar"), []byte("baz")}
	fmt.Printf("%s", bytes.Join(s, []byte(", ")))
}

Output:

foo, bar, baz

func LastIndex

func LastIndex(s, sep []byte) int

LastIndex 返回 sep 在 s 中最后一次出现的索引,若 s 中不存在 sep 则返回 -1。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Println(bytes.Index([]byte("go gopher"), []byte("go")))
	fmt.Println(bytes.LastIndex([]byte("go gopher"), []byte("go")))
	fmt.Println(bytes.LastIndex([]byte("go gopher"), []byte("rodent")))
}

Output:

0
3
-1

func LastIndexAny

func LastIndexAny(s []byte, chars string) int

LastIndexAny 将 s 解析为 UTF-8 编码的 Unicode 码点序列。 它返回 chars 中任意 Unicode 码点在 s 中最后一次出现的字节索引。 若 chars 为空或无共同码点则返回 -1。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Println(bytes.LastIndexAny([]byte("go gopher"), "MüQp"))
	fmt.Println(bytes.LastIndexAny([]byte("go 地鼠"), "地大"))
	fmt.Println(bytes.LastIndexAny([]byte("go gopher"), "z,!."))
}

Output:

5
3
-1

func LastIndexByte

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

LastIndexByte 返回 c 在 s 中最后一次出现的索引,若 s 中不存在 c 则返回 -1。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Println(bytes.LastIndexByte([]byte("go gopher"), byte('g')))
	fmt.Println(bytes.LastIndexByte([]byte("go gopher"), byte('r')))
	fmt.Println(bytes.LastIndexByte([]byte("go gopher"), byte('z')))
}

Output:

3
8
-1

func LastIndexFunc

func LastIndexFunc(s []byte, f func(rune) bool) int

LastIndexFunc 将 s 解析为 UTF-8 编码的码点序列。 它返回 s 中最后一个满足 f(c) 的 Unicode 码点的字节索引,若无则返回 -1。

Example
package main

import (
	"bytes"
	"fmt"
	"unicode"
)

func main() {
	fmt.Println(bytes.LastIndexFunc([]byte("go gopher!"), unicode.IsLetter))
	fmt.Println(bytes.LastIndexFunc([]byte("go gopher!"), unicode.IsPunct))
	fmt.Println(bytes.LastIndexFunc([]byte("go gopher!"), unicode.IsNumber))
}

Output:

8
9
-1

func Lines

func Lines(s []byte) iter.Seq[[]byte]

Lines 返回字节切片 s 中以换行符结尾的行的迭代器。 迭代器产生的行包含其结尾的换行符。 如果 s 为空,迭代器不会产生任何行。 如果 s 不以换行符结尾,最后产生的行将不以换行符结尾。 它返回一个单次使用的迭代器。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	text := []byte("Hello\nWorld\nGo Programming\n")
	for line := range bytes.Lines(text) {
		fmt.Printf("%q\n", line)
	}

}

Output:

"Hello\n"
"World\n"
"Go Programming\n"

func Map

func Map(mapping func(r rune) rune, s []byte) []byte

Map 返回字节切片 s 的副本,其中所有字符根据映射函数进行修改。 若映射返回负值,该字符将从字节切片中移除且不替换。 s 和输出中的字符均被解析为 UTF-8 编码码点。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	rot13 := func(r rune) rune {
		switch {
		case r >= 'A' && r <= 'Z':
			return 'A' + (r-'A'+13)%26
		case r >= 'a' && r <= 'z':
			return 'a' + (r-'a'+13)%26
		}
		return r
	}
	fmt.Printf("%s\n", bytes.Map(rot13, []byte("'Twas brillig and the slithy gopher...")))
}

Output:

'Gjnf oevyyvt naq gur fyvgul tbcure...

func Repeat

func Repeat(b []byte, count int) []byte

Repeat 返回由 count 个 b 副本组成的新字节切片。

若 count 为负数或 (len(b) * count) 结果溢出,会触发 panic。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Printf("ba%s", bytes.Repeat([]byte("na"), 2))
}

Output:

banana

func Replace

func Replace(s, old, new []byte, n int) []byte

Replace 返回切片 s 的副本,将前 n 个非重叠的 old 替换为 new。 若 old 为空,匹配切片开头和每个 UTF-8 序列之后, 对于 k 个码点的切片最多进行 k+1 次替换。 若 n < 0,替换次数无限制。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Printf("%s\n", bytes.Replace([]byte("oink oink oink"), []byte("k"), []byte("ky"), 2))
	fmt.Printf("%s\n", bytes.Replace([]byte("oink oink oink"), []byte("oink"), []byte("moo"), -1))
}

Output:

oinky oinky oink
moo moo moo

func ReplaceAll

func ReplaceAll(s, old, new []byte) []byte

ReplaceAll 返回切片 s 的副本,将所有非重叠的 old 替换为 new。 若 old 为空,匹配切片开头和每个 UTF-8 序列之后, 对于 k 个码点的切片最多进行 k+1 次替换。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Printf("%s\n", bytes.ReplaceAll([]byte("oink oink oink"), []byte("oink"), []byte("moo")))
}

Output:

moo moo moo

func Runes

func Runes(s []byte) []rune

Runes 将 s 解析为 UTF-8 编码的码点序列。 返回与 s 等效的字符(Unicode 码点)切片。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	rs := bytes.Runes([]byte("go gopher"))
	for _, r := range rs {
		fmt.Printf("%#U\n", r)
	}
}

Output:

U+0067 'g'
U+006F 'o'
U+0020 ' '
U+0067 'g'
U+006F 'o'
U+0070 'p'
U+0068 'h'
U+0065 'e'
U+0072 'r'

func Split

func Split(s, sep []byte) [][]byte

Split 将 s 按 sep 全部分割为多个子切片,并返回分隔符之间的子切片切片。 若 sep 为空,Split 会在每个 UTF-8 序列后进行分割。 等价于计数为 -1 的 SplitN。

如需围绕分隔符的第一个实例进行分割,参见 Cut

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Printf("%q\n", bytes.Split([]byte("a,b,c"), []byte(",")))
	fmt.Printf("%q\n", bytes.Split([]byte("a man a plan a canal panama"), []byte("a ")))
	fmt.Printf("%q\n", bytes.Split([]byte(" xyz "), []byte("")))
	fmt.Printf("%q\n", bytes.Split([]byte(""), []byte("Bernardo O'Higgins")))
}

Output:

["a" "b" "c"]
["" "man " "plan " "canal panama"]
[" " "x" "y" "z" " "]
[""]

func SplitAfter

func SplitAfter(s, sep []byte) [][]byte

SplitAfter 在 sep 每次出现后将 s 全部分割为多个子切片, 并返回这些子切片的切片。 若 sep 为空,SplitAfter 会在每个 UTF-8 序列后进行分割。 等价于计数为 -1 的 SplitAfterN。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Printf("%q\n", bytes.SplitAfter([]byte("a,b,c"), []byte(",")))
}

Output:

["a," "b," "c"]

func SplitAfterN

func SplitAfterN(s, sep []byte, n int) [][]byte

SplitAfterN 在 sep 每次出现后将 s 分割为多个子切片, 并返回这些子切片的切片。 若 sep 为空,SplitAfterN 会在每个 UTF-8 序列后进行分割。 计数参数决定返回的子切片数量:

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Printf("%q\n", bytes.SplitAfterN([]byte("a,b,c"), []byte(","), 2))
}

Output:

["a," "b,c"]

func SplitAfterSeq

func SplitAfterSeq(s, sep []byte) iter.Seq[[]byte]

SplitAfterSeq 返回 s 中在每个 sep 实例后分割的子切片的迭代器。 迭代器产生的子切片与 SplitAfter 但不会构建一个包含这些子切片的新切片。 它返回一个单次使用的迭代器。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	s := []byte("a,b,c,d")
	for part := range bytes.SplitAfterSeq(s, []byte(",")) {
		fmt.Printf("%q\n", part)
	}

}

Output:

"a,"
"b,"
"c,"
"d"

func SplitN

func SplitN(s, sep []byte, n int) [][]byte

SplitN 将 s 按 sep 分割为多个子切片,并返回分隔符之间的子切片切片。 若 sep 为空,SplitN 会在每个 UTF-8 序列后进行分割。 计数参数决定返回的子切片数量:

如需围绕分隔符的第一个实例进行分割,参见 Cut

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Printf("%q\n", bytes.SplitN([]byte("a,b,c"), []byte(","), 2))
	z := bytes.SplitN([]byte("a,b,c"), []byte(","), 0)
	fmt.Printf("%q (nil = %v)\n", z, z == nil)
}

Output:

["a" "b,c"]
[] (nil = true)

func SplitSeq

func SplitSeq(s, sep []byte) iter.Seq[[]byte]

SplitSeq 返回 s 中所有被 sep 分隔的子切片的迭代器。 迭代器产生的子切片与 Split 但不会构建一个包含这些子切片的新切片。 它返回一个单次使用的迭代器。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	s := []byte("a,b,c,d")
	for part := range bytes.SplitSeq(s, []byte(",")) {
		fmt.Printf("%q\n", part)
	}

}

Output:

"a"
"b"
"c"
"d"

func Title

func Title(s []byte) []byte

Title 将 s 视为 UTF-8 编码字节,返回副本并将所有单词开头的 Unicode 字母转换为标题大小写。

已弃用:Title 使用的单词边界规则无法正确处理 Unicode 标点符号。 请改用 golang.org/x/text/cases。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Printf("%s", bytes.Title([]byte("her royal highness")))
}

Output:

Her Royal Highness

func ToLower

func ToLower(s []byte) []byte

ToLower 返回字节切片 s 的副本,其中所有 Unicode 字母转换为小写。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Printf("%s", bytes.ToLower([]byte("Gopher")))
}

Output:

gopher

func ToLowerSpecial

func ToLowerSpecial(c unicode.SpecialCase, s []byte) []byte

ToLowerSpecial 将 s 视为 UTF-8 编码字节,返回副本并将所有 Unicode 字母转换为小写, 优先遵循特殊大小写规则。

Example
package main

import (
	"bytes"
	"fmt"
	"unicode"
)

func main() {
	str := []byte("AHOJ VÝVOJÁRİ GOLANG")
	totitle := bytes.ToLowerSpecial(unicode.AzeriCase, str)
	fmt.Println("Original : " + string(str))
	fmt.Println("ToLower : " + string(totitle))
}

Output:

Original : AHOJ VÝVOJÁRİ GOLANG
ToLower : ahoj vývojári golang

func ToTitle

func ToTitle(s []byte) []byte

ToTitle 将 s 视为 UTF-8 编码字节,返回副本并将所有 Unicode 字母转换为标题大小写。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Printf("%s\n", bytes.ToTitle([]byte("loud noises")))
	fmt.Printf("%s\n", bytes.ToTitle([]byte("брат")))
}

Output:

LOUD NOISES
БРАТ

func ToTitleSpecial

func ToTitleSpecial(c unicode.SpecialCase, s []byte) []byte

ToTitleSpecial 将 s 视为 UTF-8 编码字节,返回副本并将所有 Unicode 字母转换为标题大小写, 优先遵循特殊大小写规则。

Example
package main

import (
	"bytes"
	"fmt"
	"unicode"
)

func main() {
	str := []byte("ahoj vývojári golang")
	totitle := bytes.ToTitleSpecial(unicode.AzeriCase, str)
	fmt.Println("Original : " + string(str))
	fmt.Println("ToTitle : " + string(totitle))
}

Output:

Original : ahoj vývojári golang
ToTitle : AHOJ VÝVOJÁRİ GOLANG

func ToUpper

func ToUpper(s []byte) []byte

ToUpper 返回字节切片 s 的副本,其中所有 Unicode 字母转换为大写。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Printf("%s", bytes.ToUpper([]byte("Gopher")))
}

Output:

GOPHER

func ToUpperSpecial

func ToUpperSpecial(c unicode.SpecialCase, s []byte) []byte

ToUpperSpecial 将 s 视为 UTF-8 编码字节,返回副本并将所有 Unicode 字母转换为大写, 优先遵循特殊大小写规则。

Example
package main

import (
	"bytes"
	"fmt"
	"unicode"
)

func main() {
	str := []byte("ahoj vývojári golang")
	totitle := bytes.ToUpperSpecial(unicode.AzeriCase, str)
	fmt.Println("Original : " + string(str))
	fmt.Println("ToUpper : " + string(totitle))
}

Output:

Original : ahoj vývojári golang
ToUpper : AHOJ VÝVOJÁRİ GOLANG

func ToValidUTF8

func ToValidUTF8(s, replacement []byte) []byte

ToValidUTF8 将 s 视为 UTF-8 编码字节,返回副本并将每组表示无效 UTF-8 的字节替换为 replacement 字节(可为空)。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Printf("%s\n", bytes.ToValidUTF8([]byte("abc"), []byte("\uFFFD")))
	fmt.Printf("%s\n", bytes.ToValidUTF8([]byte("a\xffb\xC0\xAFc\xff"), []byte("")))
	fmt.Printf("%s\n", bytes.ToValidUTF8([]byte("\xed\xa0\x80"), []byte("abc")))
}

Output:

abc
abc
abc

func Trim

func Trim(s []byte, cutset string) []byte

Trim 切除 cutset 中包含的所有前导和尾部 UTF-8 码点,返回 s 的子切片。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Printf("[%q]", bytes.Trim([]byte(" !!! Achtung! Achtung! !!! "), "! "))
}

Output:

["Achtung! Achtung"]

func TrimFunc

func TrimFunc(s []byte, f func(rune) bool) []byte

TrimFunc 切除所有满足 f(c) 的前导和尾部 UTF-8 码点,返回 s 的子切片。

Example
package main

import (
	"bytes"
	"fmt"
	"unicode"
)

func main() {
	fmt.Println(string(bytes.TrimFunc([]byte("go-gopher!"), unicode.IsLetter)))
	fmt.Println(string(bytes.TrimFunc([]byte("\"go-gopher!\""), unicode.IsLetter)))
	fmt.Println(string(bytes.TrimFunc([]byte("go-gopher!"), unicode.IsPunct)))
	fmt.Println(string(bytes.TrimFunc([]byte("1234go-gopher!567"), unicode.IsNumber)))
}

Output:

-gopher!
"go-gopher!"
go-gopher
go-gopher!

func TrimLeft

func TrimLeft(s []byte, cutset string) []byte

TrimLeft 切除 cutset 中包含的所有前导 UTF-8 码点,返回 s 的子切片。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Print(string(bytes.TrimLeft([]byte("453gopher8257"), "0123456789")))
}

Output:

gopher8257

func TrimLeftFunc

func TrimLeftFunc(s []byte, f func(rune) bool) []byte

TrimLeftFunc 将 s 视为 UTF-8 编码字节,切除所有满足 f(c) 的前导 UTF-8 码点,返回子切片。

Example
package main

import (
	"bytes"
	"fmt"
	"unicode"
)

func main() {
	fmt.Println(string(bytes.TrimLeftFunc([]byte("go-gopher"), unicode.IsLetter)))
	fmt.Println(string(bytes.TrimLeftFunc([]byte("go-gopher!"), unicode.IsPunct)))
	fmt.Println(string(bytes.TrimLeftFunc([]byte("1234go-gopher!567"), unicode.IsNumber)))
}

Output:

-gopher
go-gopher!
go-gopher!567

func TrimPrefix

func TrimPrefix(s, prefix []byte) []byte

TrimPrefix 返回移除前导前缀后的 s。 若 s 不以 prefix 开头,直接返回原 s。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	var b = []byte("Goodbye,, world!")
	b = bytes.TrimPrefix(b, []byte("Goodbye,"))
	b = bytes.TrimPrefix(b, []byte("See ya,"))
	fmt.Printf("Hello%s", b)
}

Output:

Hello, world!

func TrimRight

func TrimRight(s []byte, cutset string) []byte

TrimRight 切除 cutset 中包含的所有尾部 UTF-8 码点,返回 s 的子切片。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Print(string(bytes.TrimRight([]byte("453gopher8257"), "0123456789")))
}

Output:

453gopher

func TrimRightFunc

func TrimRightFunc(s []byte, f func(rune) bool) []byte

TrimRightFunc 切除所有满足 f(c) 的尾部 UTF-8 码点,返回 s 的子切片。

Example
package main

import (
	"bytes"
	"fmt"
	"unicode"
)

func main() {
	fmt.Println(string(bytes.TrimRightFunc([]byte("go-gopher"), unicode.IsLetter)))
	fmt.Println(string(bytes.TrimRightFunc([]byte("go-gopher!"), unicode.IsPunct)))
	fmt.Println(string(bytes.TrimRightFunc([]byte("1234go-gopher!567"), unicode.IsNumber)))
}

Output:

go-
go-gopher
1234go-gopher!

func TrimSpace

func TrimSpace(s []byte) []byte

TrimSpace 切除所有 Unicode 定义的前导和尾部空白字符,返回 s 的子切片。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Printf("%s", bytes.TrimSpace([]byte(" \t\n a lone gopher \n\t\r\n")))
}

Output:

a lone gopher

func TrimSuffix

func TrimSuffix(s, suffix []byte) []byte

TrimSuffix 返回移除尾部后缀后的 s。 若 s 不以 suffix 结尾,直接返回原 s。

Example
package main

import (
	"bytes"
	"os"
)

func main() {
	var b = []byte("Hello, goodbye, etc!")
	b = bytes.TrimSuffix(b, []byte("goodbye, etc!"))
	b = bytes.TrimSuffix(b, []byte("gopher"))
	b = append(b, bytes.TrimSuffix([]byte("world!"), []byte("x!"))...)
	os.Stdout.Write(b)
}

Output:

Hello, world!

Types

type Buffer

type Buffer struct {
	// contains filtered or unexported fields
}

Buffer 是一个可变大小的字节缓冲区,提供 Buffer.ReadBuffer.Write 方法。 Buffer 的零值是一个可直接使用的空缓冲区。

Example
package main

import (
	"bytes"
	"fmt"
	"os"
)

func main() {
	var b bytes.Buffer // A Buffer needs no initialization.
	b.Write([]byte("Hello "))
	fmt.Fprintf(&b, "world!")
	b.WriteTo(os.Stdout)
}

Output:

Hello world!
Example (Reader)
package main

import (
	"bytes"
	"encoding/base64"
	"io"
	"os"
)

func main() {
	// A Buffer can turn a string or a []byte into an io.Reader.
	buf := bytes.NewBufferString("R29waGVycyBydWxlIQ==")
	dec := base64.NewDecoder(base64.StdEncoding, buf)
	io.Copy(os.Stdout, dec)
}

Output:

Gophers rule!

func NewBuffer

func NewBuffer(buf []byte) *Buffer

NewBuffer 使用 buf 作为初始内容创建并初始化一个新的 Buffer。 新的 Buffer 会接管 buf,调用方在此之后不应再使用 buf。 NewBuffer 用于准备读取已有数据的 Buffer,也可用于设置写入用内部缓冲区的初始大小。 实现该需求时,buf 应具备所需容量但长度为 0。

大多数场景下,new(Buffer)(或仅声明 Buffer 变量)足以初始化 Buffer

func NewBufferString

func NewBufferString(s string) *Buffer

NewBufferString 使用字符串 s 作为初始内容创建并初始化一个新的 Buffer。 用于准备读取已有字符串的缓冲区。

大多数场景下,new(Buffer)(或仅声明 Buffer 变量)足以初始化 Buffer

func (*Buffer) Available

func (b *Buffer) Available() int

Available 返回缓冲区中未使用的字节数。

func (*Buffer) AvailableBuffer

func (b *Buffer) AvailableBuffer() []byte

AvailableBuffer 返回一个容量为 b.Available() 的空缓冲区。 该缓冲区用于追加数据,并传入紧随其后的 Buffer.Write 调用。 该切片仅在对 b 执行下次写操作前有效。

Example
package main

import (
	"bytes"
	"os"
	"strconv"
)

func main() {
	var buf bytes.Buffer
	for i := 0; i < 4; i++ {
		b := buf.AvailableBuffer()
		b = strconv.AppendInt(b, int64(i), 10)
		b = append(b, ' ')
		buf.Write(b)
	}
	os.Stdout.Write(buf.Bytes())
}

Output:

0 1 2 3

func (*Buffer) Bytes

func (b *Buffer) Bytes() []byte

Bytes 返回一个长度为 b.Len() 的切片,包含缓冲区的未读部分。 该切片仅在下次缓冲区修改前有效(即仅在下次调用 Buffer.ReadBuffer.WriteBuffer.ResetBuffer.Truncate 等方法前有效)。 至少在下次缓冲区修改前,该切片与缓冲区内容共用底层数组, 因此直接修改切片会影响后续读取结果。

Example
package main

import (
	"bytes"
	"os"
)

func main() {
	buf := bytes.Buffer{}
	buf.Write([]byte{'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'})
	os.Stdout.Write(buf.Bytes())
}

Output:

hello world

func (*Buffer) Cap

func (b *Buffer) Cap() int

Cap 返回缓冲区底层字节切片的容量,即为缓冲区数据分配的总空间。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	buf1 := bytes.NewBuffer(make([]byte, 10))
	buf2 := bytes.NewBuffer(make([]byte, 0, 10))
	fmt.Println(buf1.Cap())
	fmt.Println(buf2.Cap())
}

Output:

10
10

func (*Buffer) Grow

func (b *Buffer) Grow(n int)

Grow 按需扩容缓冲区容量,确保能容纳额外 n 个字节。 执行 Grow(n) 后,至少可向缓冲区写入 n 个字节而无需再次分配内存。 若 n 为负数,Grow 会触发 panic。 若缓冲区无法扩容,会触发 panic 并抛出 ErrTooLarge

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	var b bytes.Buffer
	b.Grow(64)
	bb := b.Bytes()
	b.Write([]byte("64 bytes or fewer"))
	fmt.Printf("%q", bb[:b.Len()])
}

Output:

"64 bytes or fewer"

func (*Buffer) Len

func (b *Buffer) Len() int

Len 返回缓冲区未读部分的字节数; b.Len() == len(b.Bytes())。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	var b bytes.Buffer
	b.Grow(64)
	b.Write([]byte("abcde"))
	fmt.Printf("%d", b.Len())
}

Output:

5

func (*Buffer) Next

func (b *Buffer) Next(n int) []byte

Next 返回一个包含缓冲区接下来 n 个字节的切片, 移动缓冲区读取指针,效果等同于通过 Buffer.Read 返回这些字节。 若缓冲区字节数少于 n,Next 返回整个缓冲区。 该切片仅在下次调用读或写方法前有效。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	var b bytes.Buffer
	b.Grow(64)
	b.Write([]byte("abcde"))
	fmt.Printf("%s\n", b.Next(2))
	fmt.Printf("%s\n", b.Next(2))
	fmt.Printf("%s", b.Next(2))
}

Output:

ab
cd
e

func (*Buffer) Peek

func (b *Buffer) Peek(n int) ([]byte, error)

Peek 返回接下来的 n 个字节,且不移动缓冲区读取指针。 若 Peek 返回的字节数少于 n,会同时返回 io.EOF。 该切片仅在下次调用读或写方法前有效。 至少在下次缓冲区修改前,该切片与缓冲区内容共用底层数组, 因此直接修改切片会影响后续读取结果。

func (*Buffer) Read

func (b *Buffer) Read(p []byte) (n int, err error)

Read 从缓冲区读取接下来 len(p) 个字节,或直至缓冲区清空。 返回值 n 为读取的字节数。若缓冲区无数据可返回,err 为 io.EOF(len(p) 为 0 时除外); 其他情况 err 为 nil。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	var b bytes.Buffer
	b.Grow(64)
	b.Write([]byte("abcde"))
	rdbuf := make([]byte, 1)
	n, err := b.Read(rdbuf)
	if err != nil {
		panic(err)
	}
	fmt.Println(n)
	fmt.Println(b.String())
	fmt.Println(string(rdbuf))
}

Output:

1
bcde
a

func (*Buffer) ReadByte

func (b *Buffer) ReadByte() (byte, error)

ReadByte 读取并返回缓冲区的下一个字节。 若无可用字节,返回错误 io.EOF

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	var b bytes.Buffer
	b.Grow(64)
	b.Write([]byte("abcde"))
	c, err := b.ReadByte()
	if err != nil {
		panic(err)
	}
	fmt.Println(c)
	fmt.Println(b.String())
}

Output:

97
bcde

func (*Buffer) ReadBytes

func (b *Buffer) ReadBytes(delim byte) (line []byte, err error)

ReadBytes 读取数据直至输入中首次出现分隔符 delim, 返回一个包含分隔符及之前所有数据的切片。 若 ReadBytes 在找到分隔符前遇到错误, 返回错误前读取的数据和该错误(通常为 io.EOF)。 当且仅当返回的数据不以分隔符结尾时,ReadBytes 返回的 err 不为 nil。

func (*Buffer) ReadFrom

func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error)

ReadFrom 从 r 读取数据直至 EOF,并将其追加到缓冲区,按需扩容。 返回值 n 为读取的字节数。读取过程中遇到的除 io.EOF 外的错误都会被返回。 若缓冲区过大,ReadFrom 会触发 panic 并抛出 ErrTooLarge

func (*Buffer) ReadRune

func (b *Buffer) ReadRune() (r rune, size int, err error)

ReadRune 读取并返回缓冲区中下一个 UTF-8 编码的 Unicode 码点。 若无可用字节,返回错误 io.EOF。 若字节为非法 UTF-8 编码,消耗 1 个字节并返回 U+FFFD 和 1。

func (*Buffer) ReadString

func (b *Buffer) ReadString(delim byte) (line string, err error)

ReadString 读取数据直至输入中首次出现分隔符 delim, 返回一个包含分隔符及之前所有数据的字符串。 若 ReadString 在找到分隔符前遇到错误, 返回错误前读取的数据和该错误(通常为 io.EOF)。 当且仅当返回的数据不以分隔符结尾时,ReadString 返回的 err 不为 nil。

func (*Buffer) Reset

func (b *Buffer) Reset()

Reset 将缓冲区置空, 但保留底层存储空间供后续写入使用。 Reset 等价于 Buffer.Truncate

func (*Buffer) String

func (b *Buffer) String() string

String 将缓冲区未读部分的内容以字符串形式返回。 若 Buffer 为 nil 指针,返回 "<nil>"。

如需更高效地构建字符串,参见 strings.Builder 类型。

func (*Buffer) Truncate

func (b *Buffer) Truncate(n int)

Truncate 丢弃缓冲区中除前 n 个未读字节外的所有数据, 但继续使用相同的已分配存储空间。 若 n 为负数或大于缓冲区长度,会触发 panic。

func (*Buffer) UnreadByte

func (b *Buffer) UnreadByte() error

UnreadByte 撤销最近一次成功读取至少一个字节的读操作,回退最后一个字节。 若上次读取后执行了写入操作、上次读取返回错误或读取字节数为 0, UnreadByte 返回错误。

func (*Buffer) UnreadRune

func (b *Buffer) UnreadRune() error

UnreadRune 撤销上次 Buffer.ReadRune 返回的符文读取操作。 若缓冲区最近一次读写操作并非成功的 Buffer.ReadRune,UnreadRune 返回错误。 (在这一点上,它比 Buffer.UnreadByte 更严格,后者可撤销任意读操作的最后一个字节)。

func (*Buffer) Write

func (b *Buffer) Write(p []byte) (n int, err error)

Write 将 p 的内容追加到缓冲区,按需扩容。 返回值 n 为 p 的长度;err 始终为 nil。 若缓冲区过大,Write 会触发 panic 并抛出 ErrTooLarge

func (*Buffer) WriteByte

func (b *Buffer) WriteByte(c byte) error

WriteByte 将字节 c 追加到缓冲区,按需扩容。 返回的错误始终为 nil,仅为匹配 bufio.Writer 的 WriteByte 方法。 若缓冲区过大,WriteByte 会触发 panic 并抛出 ErrTooLarge

func (*Buffer) WriteRune

func (b *Buffer) WriteRune(r rune) (n int, err error)

WriteRune 将 Unicode 码点 r 的 UTF-8 编码追加到缓冲区, 返回其编码长度和错误(错误始终为 nil,仅为匹配 bufio.Writer 的 WriteRune 方法)。 缓冲区按需扩容;若缓冲区过大,WriteRune 会触发 panic 并抛出 ErrTooLarge

func (*Buffer) WriteString

func (b *Buffer) WriteString(s string) (n int, err error)

WriteString 将 s 的内容追加到缓冲区,按需扩容。 返回值 n 为 s 的长度;err 始终为 nil。 若缓冲区过大,WriteString 会触发 panic 并抛出 ErrTooLarge

func (*Buffer) WriteTo

func (b *Buffer) WriteTo(w io.Writer) (n int64, err error)

WriteTo 向 w 写入数据直至缓冲区清空或发生错误。 返回值 n 为写入的字节数;其值始终可存入 int, 但采用 int64 以匹配 io.WriterTo 接口。写入过程中遇到的任何错误都会被返回。

type Reader

type Reader struct {
	// contains filtered or unexported fields
}

Reader 通过读取字节切片实现了 io.Readerio.ReaderAtio.WriterToio.Seekerio.ByteScannerio.RuneScanner 接口。 与 Buffer 不同,Reader 是只读的且支持寻址。 Reader 的零值行为类似于读取空切片的 Reader。

func NewReader

func NewReader(b []byte) *Reader

NewReader 返回一个从 b 读取的新 Reader

func (*Reader) Len

func (r *Reader) Len() int

Len 返回切片中未读取部分的字节数。

Example
package main

import (
	"bytes"
	"fmt"
)

func main() {
	fmt.Println(bytes.NewReader([]byte("Hi!")).Len())
	fmt.Println(bytes.NewReader([]byte("こんにちは!")).Len())
}

Output:

3
16

func (*Reader) Read

func (r *Reader) Read(b []byte) (n int, err error)

Read 实现了 io.Reader 接口。

func (*Reader) ReadAt

func (r *Reader) ReadAt(b []byte, off int64) (n int, err error)

ReadAt 实现了 io.ReaderAt 接口。

func (*Reader) ReadByte

func (r *Reader) ReadByte() (byte, error)

ReadByte 实现了 io.ByteReader 接口。

func (*Reader) ReadRune

func (r *Reader) ReadRune() (ch rune, size int, err error)

ReadRune 实现了 io.RuneReader 接口。

func (*Reader) Reset

func (r *Reader) Reset(b []byte)

Reset 重置 Reader 以从 b 读取。

func (*Reader) Seek

func (r *Reader) Seek(offset int64, whence int) (int64, error)

Seek 实现了 io.Seeker 接口。

func (*Reader) Size

func (r *Reader) Size() int64

Size 返回底层字节切片的原始长度。 Size 是通过 Reader.ReadAt 可读取的字节数。 除 Reader.Reset 外,任何方法调用都不会影响该结果。

func (*Reader) UnreadByte

func (r *Reader) UnreadByte() error

UnreadByte 补充 Reader.ReadByte 实现了 io.ByteScanner 接口。

func (*Reader) UnreadRune

func (r *Reader) UnreadRune() error

UnreadRune 补充 Reader.ReadRune 实现了 io.RuneScanner 接口。

func (*Reader) WriteTo

func (r *Reader) WriteTo(w io.Writer) (n int64, err error)

WriteTo 实现了 io.WriterTo 接口。