### Scan方法中有如下代码片段一
```
if s.end > s.start || s.err != nil {
advance, token, err := s.split(s.buf[s.start:s.end], s.err != nil)
if err != nil {
if err == ErrFinalToken {
s.token = token
s.done = true
return true
}
s.setErr(err)
return false
}
.....
}
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
if atEOF && len(data) == 0 {
return 0, nil, nil
}
if i := bytes.IndexByte(data, '\n'); i >= 0 {
// We have a full newline-terminated line.
return i + 1, dropCR(data[0:i]), nil
}
// If we're at EOF, we have a final, non-terminated line. Return it.
if atEOF {
return len(data), dropCR(data), nil
}
// Request more data.
return 0, nil, nil
}
```
此段代码中,s.split实际会调用ScanLines函数,这个函数里面无论如何返回的err都是nil的,这样的话s.split后面的if err != nil是为啥呢。
### Scan代码片段二
```
const maxInt = int(^uint(0) >> 1)
if len(s.buf) >= s.maxTokenSize || len(s.buf) > maxInt/2 {
s.setErr(ErrTooLong)
return false
}
```
这里是buffer满了分配新空间,新空间溢出判断为什么要使用maxInt,在64位windows机器里面,此值是9223372036854775807即便是32位机器也有4294967295,但maxTokenSize在我机器里面仅仅是64 * 1024。为什么要设置一个这么大的值作为上限,内存明显可能不足吧。
请大神指点
虽然NewScanner里设置的是ScanLines和MaxScanTokenSize,但是split函数可以通过func (s *Scanner) Split(split SplitFunc)设置,maxTokenSize可以通过func (s *Scanner) Buffer(buf []byte, max int)设置。
正常扫描在for循环的第一个if就退出了,其他则是split没有返回一个非空token,主要是空buf和buf空间不足。可以设置空buf,所以会有一个莫名其妙的startBufSize;buf空间不足,左移数据且扩容,maxInt = int(^uint(0) >> 1),那就是2^31 - 1,maxInt / 2就是2^30,也就是GO限死了最多设置buf为2^30个字节
#3
更多评论
谢谢指教,语言层面不能做限制的思路我理解了,但是不明白的是,9223372036854775807这个数字是和len(s.buf)比较,那应该是表示byte的长度,约等于8589934591G(9223372036854775807 / 1024 /1024 / 1024)?
#2