斐波那契的问题
来源:1-1 接口的概念
宝慕林5317199
2021-06-23 20:10:46
func(g intGen) Read(p []byte)
老师说这个p可能太小,导致读的时候有问题,又说解决方案不在这个课上讲了。我百思不得其解,希望老师能否给个解决方案?
我自己打断点debug,这个p的大小是系统给初始化的,每次默认长度和容量都是4096。 完全不懂老师讲的太小啥意思?如何控制大小,什么时候会出现太小导致报错?
1回答
ccmouse
2021-06-24
同学已经研究的很深入了,找到了这个默认长度4096。是这样的,使用Scanner不会有问题。但是我们这里的Read函数必须针对所有的参数都适用,而不是仅能配合Scanner使用。
我们强行分配一个大小为1的缓冲区:
buf := make([]byte, 1)
g.Read(buf)
这样就可以使它出错。
解决的方法比较直接,我们把intGen类型做成一个struct而不是函数,用currentReader来保存读了一半的数:
type intGen struct {
gen func() int
currentReader io.Reader
}
在func(g *intGen) Read(p []byte)中,我们:
currentReader存了之前读了一半的数据,首先尝试从currentReader读取数据。
若读到了EOF,说明之前的数据读完,我们就要调用gen()函数生成下一个数,并生成新的currentReader
如果步骤1中没有读到任何数据就直接返回了EOF,那么从新的currentReader再次尝试读取。(反之有可能读到了一个尾巴,并且读到EOF,这样我们不需要再次读取)
完整代码:
type intGen struct {
gen func() int
currentReader io.Reader
}
func (g *intGen) Read(
p []byte) (n int, err error) {
err = io.EOF
if g.currentReader != nil {
n, err = g.currentReader.Read(p)
}
if err == io.EOF {
next := g.gen()
s := fmt.Sprintf("%d", next)
g.currentReader = strings.NewReader(s)
if n == 0 {
n, err = g.currentReader.Read(p)
}
}
return n, err
}
Go playground运行结果:https://play.studygolang.com/p/gQKQtbHKfRL
相似问题