- string:
- 不可变的
- 副本不用拷贝, 使用同一个底层数组
- strings.Builder
- 已存在内容不可变
- 可以拼接
- 减少内存分配和内容拷贝
- 可以重置内容, 可以重用
- 不可以复制(赋值,函数传递)后再使用其方法
- 可以复制指针, 但是要解决并发安全的问题
- Grow() 扩容, 如果容量够就不扩容
- Reset() 重置
- strings.Reader
- Len() 未读数据长度
- Size() 数据总长度
- Seek(offset int64, whence int)
- offset - 从 whence 的位置偏移量, 可以是负数
- whence
- SeekStart 开始的位置
- SeekCurrent 当前记录的位置
- SeekEnd 结束的位置
上代码, 自己品:
package main
import (
"fmt"
"strings"
)
func main() {
var builder strings.Builder
fmt.Println("len: ", builder.Len(), builder.Cap()) // 0 0
builder.Grow(10)
fmt.Println("len: ", builder.Len(), builder.Cap()) // 0 10
builder.Grow(10) // 只要这里的 <= 10 都一样
fmt.Println("len: ", builder.Len(), builder.Cap()) // 0 10
builder.Grow(11) // 这里 > 10 是 10 * 2 + 11
fmt.Println("len: ", builder.Len(), builder.Cap()) // 0 31
builder.WriteString("0123456789012345678901234567891")
fmt.Println("len: ", builder.Len(), builder.Cap()) // 31 31
builder.WriteString("23")
fmt.Println("len: ", builder.Len(), builder.Cap()) // 33, 64
builder.Grow(70) // 这里 > 64 - 33 是 64 * 2 + 70
fmt.Println("len: ", builder.Len(), builder.Cap()) // 33, 64
builder.Reset()
fmt.Println("len: ", builder.Len(), builder.Cap()) // 0, 0
}
package main
import (
"fmt"
"strings"
)
func main() {
var builder strings.Builder
fmt.Println("len: ", builder.Len(), builder.Cap()) // 0 0
builder.Grow(10)
fmt.Println("len: ", builder.Len(), builder.Cap()) // 0 10
builder2 := builder // 不可以复制
builder2.WriteString("123") // panic: strings: illegal use of non-zero Builder copied by value
}
package main
import (
"fmt"
"strings"
)
func main() {
var reader *strings.Reader = strings.NewReader("0123456789")
ch, size, err := reader.ReadRune()
fmt.Println("ch: ", ch) // 48
fmt.Println("size: ", size) // 1
fmt.Println("err: ", err) // <nil>
err = reader.UnreadRune() // 配合 ReadRune 使用, 会去到上一个位置
fmt.Println("err: ", err) // <nil>
err = reader.UnreadRune() // 配合 ReadRune 使用, 会去到上一个位置
fmt.Println("err: ", err) // strings.Reader.UnreadRune: at beginning of string
b, err := reader.ReadByte()
fmt.Println("b: ", b) // 49
fmt.Println("err: ", err) // <nil>
}
package main
import (
"fmt"
"strings"
)
func main() {
var reader *strings.Reader = strings.NewReader("0123456789")
fmt.Println(reader.Len(), reader.Size()) // 10 10
var b []byte
b = make([]byte, 6)
c, err := reader.Read(b)
if err != nil {
fmt.Println("err:", err)
}
fmt.Println("c: ", c) // 6
fmt.Println("b: ", b) // [48 49 50 51 52 53]
fmt.Println(reader.Len(), reader.Size()) // 4 10
}
package main
import (
"fmt"
"io"
"strings"
)
func main() {
var reader *strings.Reader = strings.NewReader("0123456789")
fmt.Println(reader.Len(), reader.Size()) // 10 10
var b []byte
// b len 是0, 所以不读取任何内容
c, err := reader.Read(b)
if err != nil {
fmt.Println("err:", err)
}
fmt.Println("c: ", c) // 0
fmt.Println("b: ", b) // []
// b len 是0, 所以不读取任何内容, 有容量也没用
b = make([]byte, 0, 5)
c, err = reader.Read(b)
if err != nil {
fmt.Println("err:", err)
}
fmt.Println("c: ", c) // 0
fmt.Println("b: ", b) // []
// 读取 0 - 4 的内容
b = make([]byte, 5)
c, err = reader.Read(b)
if err != nil {
fmt.Println("err:", err)
}
fmt.Println("c: ", c) // 5
fmt.Println("b: ", b) // [48 49 50 51 52]
// 从 8 开始读 5 个, 只能读到 8-9, 但是 计数不会改变
b = make([]byte, 5)
c, err = reader.ReadAt(b, 8)
if err != nil {
fmt.Println("err:", err) // EOF
}
fmt.Println("c: ", c) // 2
fmt.Println("b: ", b) // [56 57 0 0 0]
// 读取 3 - 7
bb := make([]byte, 5)
c, err = reader.Read(bb)
if err != nil {
fmt.Println("err:", err)
}
fmt.Println("c: ", c) // 5
fmt.Println("b: ", bb) // [53 54 55 56 57]
// 计数器从结束位置向前 5 个位置
i, err := reader.Seek(-5, io.SeekEnd)
if err != nil {
fmt.Println("err:", err)
}
fmt.Println("i: ", i) // 5
// 读取 5 - 9 的数据
b = make([]byte, 5, 5)
c, err = reader.Read(b)
if err != nil {
fmt.Println("err:", err)
}
fmt.Println("c: ", c) // 5
fmt.Println("b: ", b) // [53 54 55 56 57]
reader.Reset("a")
fmt.Println(reader.Len(), reader.Size()) // 1 1
}