-
Notifications
You must be signed in to change notification settings - Fork 0
/
第 07.02.01 章、bytes 包
537 lines (334 loc) · 15.6 KB
/
第 07.02.01 章、bytes 包
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
总览
bytes 包实现了操作 []byte 的函数
它与 strings 包的构架类似
常量
MinRead 是调用 Buffer.ReadFrom 时传入 Read 中的最小的 slice 大小
只要 Buffer 具有的空间超过,持有 r 的内容容量,至少 MinRead 字节的空间,
ReadFrom 就不会增长底层的 buffer
const MinRead = 512
变量
若无法为缓存分配子厚存储数据的内存,ErrTooLarge 就会被传入 panic 中
var ErrTooLarge = errors.New("bytes.Buufer: too large")
Compare(a,b []byte) int
返回一个整数,按字典顺序比较两个 []byte
若 a == b,则为 0
若 a < b,则为 -1
若 a > b,则为 +1
一个 nil 参数等价于空字符串
EG.
// 将 Compare 的结果与 0 做比较,来解析结果
var a, b []byte
if bytes.Compare(a, b) < 0 {
// a 小于 b
}
if bytes.Compare(a, b) <= 0 {
// a 小于等于 b
}
if bytes.Compare(a, b) > 0 {
// a 大于 b
}
if bytes.Compare(a, b) >= 0 {
// a 大于等于 b
}
// 对于等价比较,使用 Equal 优于 Compare
if bytes.Equal(a, b) {
// a 等于 b
}
if !bytes.Equal(a, b) {
// a 不等于 b
}
EG.【Search】
// 二进制搜索已找到匹配的 []byte
var needle []byte
var haystack [][]byte // 假设已经排序
i := sort.Search(len(haystack), func(i int) bool {
// 返回 haystack[i] >= needle.
return bytes.Compare(haystack[i], needle) >= 0
})
if i < len(haystack) && bytes.Equal(haystack[i], needle) {
// 找到啦!
}
Contains(b, subslice []byte) bool
报告 b 中是否包含子切片
EG.
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("")))
ContainsAny(b []byte, chars string) bool
报告 b 中是否包含 chars 中具有的任何 UTF-8 编码的 Unicode 码点
ContainsRune(b []byte, r rune) bool
报告 b 中是否含有 Unicode 码点 r
Count(s, sep []byte) int
计算 s 中非重叠出现的 sep
若 sep 时空 slice,本函数返回 1 + s 中出现的 Unicode 码点数
EG.
fmt.Println(bytes.Count([]byte("cheese"), []byte("e")))
fmt.Println(bytes.Count([]byte("five"), []byte(""))) // 在每个 rune 之前和之后
Equal(a, b []byte) bool
返回一个布尔值报告了 a 和 b 是否具有相同长度且具有相同的内容
一个 nil 参数等价于一个空 slice
EqualFold(s, t []byte) bool
报告 s 和 t,解析为 UTF-8 字符串时,是否在 Unicode case-folding 的情况下等价
EG.
fmt.Println(bytes.EqualFold([]byte("Go"), []byte("go")))
Fields(s []byte) [][]byte
通过以一个或多个连续的 white space 字符作为分隔符,分割 s,返回获得的子 slice s,
若 s 仅含有 white space,则返回空列表
EG.
fmt.Printf("Fields are: %q", bytes.Fields([]byte(" foo bar baz ")))
FieldsFunc(s []byte, f func(rune) bool) [][]byte
把 s 解析 UTF-8 编码的 Unicode 码点序列
每当遇到满足 f(c) 的码点 c,本函数都在 c 处分离 slice s,并返回 s 的子 slice 所组成的 slice
若所有 s 中的码点都满足 f(c),或者 len(s)==0,那么返回一个空 slice
本函数不保证它调用 f(c) 的顺序
对于给定的 c,若 f 不能稳定返回值,则本函数可能崩溃
EG.
f := func(c rune) bool {
return !unicode.IsLetter(c) && !unicode.IsNumber(c)
}
fmt.Printf("Fields are: %q", bytes.FieldsFunc([]byte(" foo1;bar2,baz3..."), f))
HasPrefix(s, prefix []byte) bool
测试 slice s 是否以 prefix 开始
EG.
fmt.Println(bytes.HasPrefix([]byte("Gopher"), []byte("Go")))
fmt.Println(bytes.HasPrefix([]byte("Gopher"), []byte("C")))
fmt.Println(bytes.HasPrefix([]byte("Gopher"), []byte("")))
HasSuffix(s, suffix []byte) bool
测试 slice s 是否以 suffix 结束
EG.
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("")))
Index(s, sep []byte) int
返回 s 中第一个 sep 的实例的索引,若 sep 并未出现在 s 中,则返回 -1
EG.
fmt.Println(bytes.Index([]byte("chicken"), []byte("ken")))
fmt.Println(bytes.Index([]byte("chicken"), []byte("dmr")))
IndexAny(s []byte, chars string) int
将 s 解析为 UTF-8 编码的 Unicode 码点序列
返回 s 中首个出现的任何存在于 chars 中的 Unicode 码点的索引
若 chars 为空,或者未能找到共有的码点时,返回 -1
EG.
fmt.Println(bytes.IndexAny([]byte("chicken"), "aeiouy"))
fmt.Println(bytes.IndexAny([]byte("crwth"), "aeiouy"))
IndexByte(s []byte, c byte) int
IndexFunc(s []byte, f func(r rune) bool) int
同上,但针对不同类型来进行测试和返回
IndexRune(s []byte, r rune) int
特别的,当 r 是 utf8.RuneError,它返回第一个遇到的非法 UTF-8 字节序列
LastIndex(s, sep []byte) int
LastIndexAny(s []byte, chars string) int
LastIndexByte(s []byte, c byte) int
LastIndexFunc(s []byte, f func(r rune) bool) int
同上,但返回的是最后一个对应的内容的索引
Join(s [][]byte, sep []byte) []byte
将 s 的元素合并为一个新的 []byte
分隔符将置于结果 slice 的两个元素之间
Map(mapping func(r rune) rune, s []byte) []byte
返回 slice s 的一个拷贝,其中的每个字符都经过 mapping 函数的修改
若 mapping 返回了一个负值,字符会直接从字符串中丢弃
s 和 输出的字符都被解析为 UTF-8 编码的码点
EG.
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", bytes.Map(rot13, []byte("'Twas brillig and the slithy gopher...")))
Repeat(b []byte, count int) []byte
返回一个新的 []byte,其中包含 count 个 b
若 count 为负值或者 len(b) * count 溢出,则产生 panic
EG.
fmt.Printf("ba%s", bytes.Repeat([]byte("na"), 2))
Replace(s, old, new []byte, n int) []byte
返回 slice s 的拷贝,其中前 n 个非重叠的 old 会被替换为 new
若 old 为空,则它匹配上 slice 的开头,以及每个 UTF-8 序列的后面,
对于 k 字符长度的 slice,产生 k + 1 个替换
若 n < 0,就不限制替换的数量
EG.
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))
Runes(s []byte) []rune
返回等价于 s 的 []rune(Unicode code points)
Split(s, sep []byte) [][]byte
通过寻找 sep 来分割 slice s,并返回分隔符之间的子 slice
若 sep 为空,本函数在每个 UTF-8 序列后分割
本函数等价于 SplitN 的 n 值为 -1 时的情况
EG.
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")))
SplitAfter(s, sep []byte) [][]byte
在每个 sep 的实例之后切开 s,并返回所有的子 slice
EG.
fmt.Printf("%q\n", bytes.SplitAfter([]byte("a,b,c"), []byte(",")))
SplitN(s, sep []byte, n int) [][]byte
SplitAfterN(s, sep []byte, n int) [][]byte
类比上两个函数
Title(s []byte) []byte
ToLower(s []byte) []byte
ToLowerSpecial(c unicode.SpecialCase, s []byte) []byte
ToTitle(s []byte) []byte
ToTitleSpecial(c unicode,SpecialCase, s []byte) []byte
ToUpper(s []byte) []byte
ToUpperSpecial(c unicode.SpecialCase, s []byte) []byte
Trim(s []byte, cutset string) []byte
TrimFunc(s []byte, f func(r rune) bool) []byte
TrimLeft(s []byte, cutset string) []byte
TrimLeftFunc(s []byte, f func(r rune) bool) []byte
TrimRight(s []byte, cutset string) []byte
TrimRightFunc(s []byte, f func(r rune) bool) []byte
TrimSpace(s []byte) []byte
TrimPrefix(s, prefix []byte) []byte
TrimSuffix(s, suffix []byte) []byte
上述函数参见 strings 包对应的函数
Buffer struct 类型
一个 Buffer 是一个可变长度的字节缓存,其具有 Read 和 Write 方法
Buffer 的零值是一个等待使用的空的缓存
type Buffer struct {
// 包含过滤或未导出字段
}
EG.
var b bytes.Buffer // Buffer 不需要被初始化
b.Write([]byte("Hello "))
fmt.Fprintf(&b, "world!")
b.WriteTo(os.Stdout)
EG.【Reader】
// Buffer 可将字符串或 []byte 转换为 io.Reader
buf := bytes.NewBufferString("R29waGVycyBydWxlIQ==")
dec := base64.NewDecoder(base64.StdEncoding, buf)
io.Copy(os.Stdout, dec)
NewBuffer(buf []byte) *Buffer
创建并初始化一个新的 Buffer,其使用 buf 作为初始值
新的 Buffer 接管 buf 的所有权,而调用者不应该在这次调用之后再次使用 buf
本函数意在准备好一个 Buffer 来读取已经存在的数据
它可以用来限制写入的内部缓存的大小
为了达到这个目的,buf 应该具有所需容量,但长度为 0
大多数情况下,new(Buffer)(或直接声明一个 Buffer 变量)就足够初始化一个 Buffer
NewBufferString(s string) *Buffer
创建并初始化一个新的 Buffer,其使用字符串作为它的初始内容
它意在准备好可以读取一个已经存在的字符串的的缓存
大多数情况下,new(Buffer)(或直接声明一个 Buffer 变量)就足够初始化一个 Buffer
(b *Buffer) Bytes() []byte
返回一个长度为 b.Len() 的 slice,其持有缓存中未读出的部分
在下一次的缓存修改之前(也就是,下一次调用如 Read、Write、Reset、Truncate 等方法之前),
slice 都是有效的
slice 至少在下次缓存修改之前都是缓存的别称,所以立刻修改 slice 将会影响未来读取的结果
(b *Buffer) Cap() int
返回缓存的底层字节 slice 的容量,也就是,为缓存数据分配的总空间
(b *Buffer) Grow(n int)
若需要,增长缓存的容量,来保证有空间来读取后面 n 字节的数据
在 Grow(n) 之后,至少有 n 字节的空间可以用于写入,而不需要另外分配
若 n 为负值, Grow 产生 panic
若缓存不能增长,则以 ErrTooLarge 产生 panic
EG.
var b bytes.Buffer
b.Grow(64)
bb := b.Bytes()
b.Write([]byte("64 bytes or fewer"))
fmt.Printf("%q", bb[:b.Len()])
(b *Buffer) Len() int
返回缓存中未读取的字节的数量;
b.Len() == len(b.Bytes())
(b *Buffer) Next(n int) []byte
从缓存中返回一个 slice,其包含了下 n 个字节的数据,
同时移动缓存,就像数据被 Read 返回一样
若缓存小于 n 字节,本函数返回整个缓存
slice 仅在下次调用读或写方法前才是有效的
(b *Buffer) Read(p []byte) (n int, err error)
从缓存中读取下 len(p) 字节,或直到耗尽缓存
返回值 n 为读取的字节数
若缓存没有可以返回的数据,err 为 io.EOF(除非 len(p) 为 0);
其他情况为 nil
(b *Buffer) ReadByte() (byte, error)
读取并返回缓存中的下一个字节
若没有字节可用,它返回 error io.EOF
(b *Buffer) ReadBytes(delim byte) (line []byte, err error)
读取直到第一次遇到输入中的 delim,返回一个 slice,包含了已经读取的数据和 delimiter
若本函数在找到 delimiter 之前就遇到了错误,它返回错误之前的数据,以及错误本身(通常为 io.EOF)
当且仅当数据不以 delim 作为结尾时,本函数返回 err != nil
(b *Buffer) ReadFrom(r io.Reader) (n int64, err error)
从 r 中读取数据,直到 EOF,并将数据追加至缓存中,若需要则增长缓存
返回值 n 是读取的字节数
除了 io.EOF 之外,任何读取到的错误同样会被返回
若缓存变得太大,本函数将会以 ErrTooLarge 产生 panic
(b *Buffer) ReadRune() (r rune, size int, err error)
从缓存中读取并返回下一个 UTF-8 编码的 Unicode 码点
若没有数据可用,error 返回 io.EOF
若数据为错误的 UTF-8 编码,它消耗一个字节,并返回 U+FFFD, 1
(b *Buffer) ReadString(delim byte) (line string, err error)
读取直到遇到输入中的第一个 delim,返回读取到的数据,包含 delimiter 本身
若本方法在找到一个 delimiter 之前遇到了错误,则它返回遇到错误前所读取的数据,以及错误本身(通常为 io.EOF)
当且仅当返回值不以 delim 结尾时, err != nil
(b *Buffer) Reset()
将缓存重置为空,但保留底层的存储空间,以便未来写入时使用
本方法等价于 Truncate(0)
(b *Buffer) String() string
将未读取的缓存的内容当做字符串返回
若 Buffer 是 nil 指针,它返回 "<nil>"
(b *Buffer) Truncate(n int)
从缓存中,取消除了前 n 个字节之外所有的数据,但继续使用相同的已分配存储空间
若 n 为负数,或者长度大于缓存大小,它 panic
(b *Buffer) UnreadByte() error
取消读取最后一个字节,该字节来自于,最近一次成功读取至少一个字节的读取操作,所读取的数据
以下情况,本方法返回一个错误,
若最后一次读取操作之后发生了写入操作,
若最后一次读取操作返回了错误,
若读取 操作读取的了 0 字节
(b *Buffer) UnreadRune() error
取消读取最后一次运行 ReadRune 所返回的 rune
若最近一次读或写操作,并非成功的 ReadRune,本方法都返回一个错误
(在这个层面上来说,它比 UnreadByte 要严格,UreadByte 会从任何读取操作中取消最后一字节的读取)
(b *Buffer) Write(p []byte) (n int, err error)
将 p 的内容追加至缓存中,若需要则增长缓存
返回值 n 是 p 的长度,err 永远为 nil
若缓存过大,则本方法将以 ErrTooLarge 产生 panic
(b *Buffer) WriteByte(c byte) error
将字节 c 追加至缓存中,若需要则增长缓存
返回的 error 应该永远是 nil,但会匹配 bufio.Writer 的 WriteByte
若缓存过大,则本方法将以 ErrTooLarge 产生 panic
(b *Buffer) WriteRune(r rune) (n int, err error)
将 UTF-8 编码的 Unicode 码点 r 追加至缓存中,返回其长度,以及任何错误,
返回的 error 应该永远是 nil,但会匹配 bufio.Writer 的 WriteRune
缓存会依据需要增长;若缓存过大,则本方法将以 ErrTooLarge 产生 panic
(b *Buffer) WriteString(s string) (n int, err error)
将 s 的内容追加至缓存中,若需要则增长缓存
返回值 n 是 s 的长度,err 将永远为 nil
若缓存过大,则本方法将以 ErrTooLarge 产生 panic
(b *Buffer) WriteTo(w io.Writer) (n int64, err error)
将数据写入 w 直到缓存耗尽或者遇到一个错误
返回值 n 是写入的字节数;它永远在 int 的范围内,但本身是 int64 来匹配 io.WriterTo 接口
任何在写入过程中遇到的错误也会一并返回
Reader struct 类型
Reader 实现了从一个 []byte 读取数据的 io.Reader io.ReadAt io.WriteTo io.Seeker io.ByteScanner io.RuneScanner 接口
与 Buffer 不同,Reader 为仅读的,且支持搜索
type Reader struct {
// 包含过滤或未导出的字段
}
NewReader(b []byte) *Reader
返回从 b 中读取数据的新 Reader
(r *Reader) Len() int
以字节为单位,返回 slice 中未读取部分的长度
(r *Reader) Read(b []byte) (n int, err error)
(r *Reader) ReadAt(b []byte, off int64) (n int, err error)
(r *Reader) ReadByte() (byte, error)
(r *Reader) ReadRune() (ch rune, size int, err error)
(r *Reader) Reset(b []byte)
将 Reader 重置为从 b 中读取
(r *Reader) Seek(offset int64, whence int) (int64, error)
实现了 io.Seeker 接口
(r *Reader) Size() int64
返回底层 []byte 的原始长度
本函数的返回值是,通过 ReadAt 能读取的字节数量
返回值永远相同,并不会受到其他方法的影响
(r *Reader) UnreadByte() error
(r *Reader) UnreadRune() error
(r *Reader) WriteTo(w io.Writer) (n int64, err error)
实现了 io.WriterTo 接口