go bufio.splitFunc()

本文探讨了如何使用自定义splitFunc在bufio.Scanner中实现数字组的扫描,针对初始缓冲区大小不同(小于和大于数据量),展示了两种场景的执行流程和结果。通过实例演示了如何处理扫描过程中的数据解析和错误处理。
摘要由CSDN通过智能技术生成

原理

splitFunc有go内置的4中,当然也支持自定义:
	type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)
	splitFUnc的功能就是:根据两个参数返回下一次Scan需要前进几个字节(advance),分割出来的数据(token),以及错误(err)。
	参数:
		-- data(字节切片): 	 缓冲区的有效数据
		-- atEOF(bool):		是否已经输入完成(scanner是否扫描到源的结尾了),若没有则duplicate扩容!
	返回值:
		-- advance(int):	Scan需要前进几个字节(advance)
		-- token(字节切片):	 分割出来的数据
		-- err(error):		错误

	返回值可以在go内置4个splitFunc的基础上获取:
		例如scanWord:func bufio.ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error)

扫描数字组(初始buffer小于数据量)

func scanIntGroup1() {
	ir := strings.NewReader("10000000000 11111111111 12222222222 13333333333")
	bs := bufio.NewScanner(ir)

	// 再scanWords()基础上实现scanTelephoneNum()
	split := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
		fmt.Printf("scanner是否扫描到EOF:%t,  缓冲区有效数据的数量:%d,  有效数据的内容:%s\n", atEOF, len(data), data)
		advance, token, err = bufio.ScanWords(data, atEOF)
		// 没有错误且内容不为空的时候进行处理
		if err == nil && token != nil {
			_, err = strconv.ParseInt(string(token), 10, 64) // 将token中10进制的字符串转换为int64
			if err != nil {
				panic(err)
			}
		}
		return
	}

	// 将scanner初始缓冲区长度设置为2字节,max to 65536
	buf := make([]byte, 2)
	bs.Buffer(buf, bufio.MaxScanTokenSize)
	bs.Split(split)

	// 读取
	i := 1
	for bs.Scan() {
		fmt.Printf("扫描到的第%d个匹配项:%v\n", i, bs.Text())
		i++
	}
}

扫描数字组(初始buffer大于数据量)

func scanIntGroup2() {
	ir := strings.NewReader("10000000000 11111111111 12222222222 13333333333")
	bs := bufio.NewScanner(ir)

	// 再scanWords()基础上实现scanTelephoneNum()
	split := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
		fmt.Printf("scanner是否扫描到EOF:%t,  scanner扫描的数据长度:%d,  scanner扫描数据的内容:%s\n", atEOF, len(data), data)
		advance, token, err = bufio.ScanWords(data, atEOF)
		// 没有错误且内容不为空的时候进行处理
		if err == nil && token != nil {
			_, err = strconv.ParseInt(string(token), 10, 64) // 将token中10进制的字符串转换为int64
			if err != nil {
				panic(err)
			}
		}
		return
	}

	// 将scanner初始缓冲区长度设置为2字节,max to 65536
	// buf := make([]byte, 2)
	// bs.Buffer(buf, bufio.MaxScanTokenSize)
	bs.Split(split)

	// 读取
	i := 1
	for bs.Scan() {
		fmt.Printf("扫描到的第%d个匹配项:%v\n", i, bs.Text())
		i++
	}
}

执行结果

func main() {
	scanIntGroup1()
	fmt.Println()
	fmt.Println("---------------------------------gorgeous separator---------------------------------")
	fmt.Println()
	scanIntGroup2()
}

图片: 在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值