什么"扫描将扫描仪推进到下一个令牌"在Go的bufio.Scanner中意味着什么?

时间:2017-06-06 04:19:52

标签: go

根据Scanner.scan documentsScan() 将扫描仪推进到下一个令牌,但这意味着什么?我发现Scanner.TextScanner.Bytes可能会有所不同,这令人费解。

此代码并不总是会导致错误,但随着文件变大,它会:

func TestScanner(t *testing.T) {
    path := "/tmp/test.txt"
    f, err := os.Open(path)
    if err != nil {
        panic(fmt.Sprint("failed to open ", path))
    }
    defer f.Close()
    scanner := bufio.NewScanner(f)

    bs := make([][]byte, 0)
    for scanner.Scan() {
        bs = append(bs, scanner.Bytes())
    }

    f, err = os.Open(path)
    if err != nil {
        panic(fmt.Sprint("failed to open ", path))
    }
    defer f.Close()
    scanner = bufio.NewScanner(f)
    ss := make([]string, 0)
    for scanner.Scan() {
        ss = append(ss, scanner.Text())
    }

    for i, b := range bs {
        if string(b) != ss[i] {
            t.Errorf("expect %s, got %s", ss[i], string(b))
        }
    }
}

1 个答案:

答案 0 :(得分:3)

令牌由扫描仪split function定义。当split函数找到一个令牌或者出现错误时,Scan()会返回。

String()和Bytes()方法都返回当前标记。 String()方法returns a copy of the token。 Bytes()方法不分配内存和returns a slice,它们可能使用后续调用Scan()时覆盖的后备数组。

从字节()返回

Copy the slice以避免此问题:

for scanner.Scan() {
    bs = append(bs, append([]byte(nil), scanner.Bytes()...))
}