Go-字符串的那些事

  • string:
    • 不可变的
    • 副本不用拷贝, 使用同一个底层数组
  • strings.Builder
    • 已存在内容不可变
    • 可以拼接
    • 减少内存分配和内容拷贝
    • 可以重置内容, 可以重用
    • 不可以复制(赋值,函数传递)后再使用其方法
    • 可以复制指针, 但是要解决并发安全的问题
    • Grow() 扩容, 如果容量够就不扩容
    • Reset() 重置
  • strings.Reader
    • Len() 未读数据长度
    • Size() 数据总长度
    • Seek(offset int64, whence int)
      • offset - 从 whence 的位置偏移量, 可以是负数
      • whence
        • SeekStart 开始的位置
        • SeekCurrent 当前记录的位置
        • SeekEnd 结束的位置

上代码, 自己品:

package main

import (
	"fmt"
	"unicode/utf8"
)

func main() {
	str := "Go编程"

	fmt.Println(len(str))                    // 8
	fmt.Println(utf8.RuneCountInString(str)) // 4
}
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")

	ch, size, err := reader.ReadRune()
	fmt.Println("ch: ", ch)     // 48
	fmt.Println("size: ", size) // 1
	fmt.Println("err: ", err)   // <nil>

	ch, size, err = reader.ReadRune()
	fmt.Println("ch: ", ch)     // 49
	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: previous operation was not ReadRune

	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")

	ch, err := reader.ReadByte()
	fmt.Println("ch: ", ch)   // 48
	fmt.Println("err: ", err) // <nil>

	err = reader.UnreadByte() // 配合 ReadByte 使用, 回到上一个位置
	fmt.Println("err: ", err) // <nil>

	err = reader.UnreadByte() // 计数位置是 0, 不能再向前读取
	fmt.Println("err: ", err) // strings.Reader.UnreadByte: at beginning of string

}
package main

import (
	"fmt"
	"strings"
)

func main() {
	var reader *strings.Reader = strings.NewReader("0123456789")

	ch, err := reader.ReadByte()
	fmt.Println("ch: ", ch)   // 48
	fmt.Println("err: ", err) // <nil>

	ch, err = reader.ReadByte()
	fmt.Println("ch: ", ch)   // 49
	fmt.Println("err: ", err) // <nil>

	err = reader.UnreadByte() // 配合 ReadByte 使用, 回到上一个位置
	fmt.Println("err: ", err) // <nil>

	err = reader.UnreadByte()
	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
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值