斐波那契的问题

斐波那契的问题

func(g intGen) Read(p []byte)

老师说这个p可能太小,导致读的时候有问题,又说解决方案不在这个课上讲了。我百思不得其解,希望老师能否给个解决方案?


我自己打断点debug,这个p的大小是系统给初始化的,每次默认长度和容量都是4096。 完全不懂老师讲的太小啥意思?如何控制大小,什么时候会出现太小导致报错?

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
ccmouse 2021-06-24 18:08:06

同学已经研究的很深入了,找到了这个默认长度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)中,我们:

  1. currentReader存了之前读了一半的数据,首先尝试从currentReader读取数据。

  2. 若读到了EOF,说明之前的数据读完,我们就要调用gen()函数生成下一个数,并生成新的currentReader

  3. 如果步骤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

  • 提问者 宝慕林5317199 #1

    感谢老师回复。不过我还是有疑惑,buf := make([]byte, 1),虽然buf长度是1,但是它可以自动扩容啊。我测试了下也不会报错,不知道是不和老师说的场景不一样。


    func main() {
      gen := Fibonacci()
      for i := 0; i < 100; i++ {
         fmt.Println(gen())
      }
      //printFileContents(gen)
      buf := make([]byte, 1)
      for i := 0; i < 5; i++ {

         n, err := gen.Read(buf)
         if err != nil {
            fmt.Println("error:", err)
         }
         fmt.Println("n:", n)
      }


    2021-06-25 10:46:09
  • 提问者 宝慕林5317199 #2
    func (g intGen) Read(p []byte) (n int, err error) {
      next := g()
      //if next > 1000000 {
      // return 0, io.EOF
      //}

    大小限制注释掉了。

    2021-06-25 10:48:24
  • ccmouse 回复 提问者 宝慕林5317199 #3

    我也试了一下,不报错,但是n总是1,另外把buf打印一下,会看到都只有一位数。我写了一段演示。

    ​https://play.studygolang.com/p/Ag2-uVg3aQc

    2021-06-27 10:00:23
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师