【问题标题】:Golang returning functionsGolang 返回函数
【发布时间】:2018-06-25 16:01:35
【问题描述】:

谁能解释为什么打印的是 0 和 1 而不是其他任何东西?谢谢!

func makeFunction(name string) func() {
    fmt.Println("00000")
    return func() {
        makeFunction2("abcef")
    }
}

func makeFunction2(name string) func() {
    fmt.Println("11111")
    return func() {
        makeFunction3("safsf")
    }
}

func makeFunction3(name string) func() {
    fmt.Println("33333")
    return func() {
        fmt.Printf("444444")
    }
}

func main() {
    f := makeFunction("hellooo")
    f()
}

谁能解释为什么打印的是 0 和 1 而不是其他任何东西?谢谢!

【问题讨论】:

  • 因为您从不调用makeFunction3,它的返回值,并且从不打印name 值?我不确定你的期望。
  • 如果您要调用具有相同签名的函数链,我建议您看一下在 Go 中实现 FSM(有限状态机)。这不是一个成熟的 FSM,但它提供了本质,这使得这些任务更加清晰。请参阅 Rob Pike youtu.be/HxaD_trXwRE?t=14m7s 的这一部分

标签: go nested-function


【解决方案1】:

让我们按照程序流程:

  1. main 开始。
  2. main 致电makeFunction
  3. makeFunction 打印 00000,并返回一个匿名函数。
  4. 回到main,我们调用上一次调用返回的匿名函数。
  5. 匿名函数调用makeFunction2
  6. makeFunction2 打印 11111,并返回一个匿名函数。
  7. main 返回。

因为在上述第 6 步之后返回值被丢弃,所以没有打印任何其他内容。

【讨论】:

    【解决方案2】:

    让我们看看你的main

    第 1 行

    f := makeFunction("hellooo")
    
    • 副作用:打印“00000”
    • 返回值:执行makeFunction2("abcef")的匿名函数,分配给标识符f

    第 2 行

    f()
    

    相当于:

    _ = f()
    
    • 副作用:打印“11111”
    • 返回值:执行makeFunction3("safsf")的匿名函数,被丢弃(您没有分配f()的返回值)。

    makeFunction3 从未分配给任何标识符,也从未调用过。

    【讨论】:

      【解决方案3】:

      要打印 3,您必须调用两次:

      f()()
      

      要打印 4 也可以:

      f()()()
      

      因为……

      // prints "00000" and returns a function that if run
      // will invoked `makeFunction2`
      f := makeFunction("hello")
      
      // `makeFunction2` is called, printing "11111" and returns 
      // a function that if run will invoked `makeFunction3`
      f1 := f()
      
      // `makeFunction3` is called, printing "33333" and returns
      // a function that if run will invoked `makeFunction4`
      f2 := f1()
      

      测试题,如果你这样做会打印出什么?

      f := makeFunction("Hello")()()
      f()
      

      这被称为柯里化或关闭,但在您的示例中,您没有关闭任何本地值,因此后者失去了意义。

      【讨论】:

        【解决方案4】:

        makeFunction 只返回函数makeFunction2。因为这不是递归函数。如果您希望表现得像递归函数,那么您应该将 return func(){} 更改为 (return makeFunction2 or 3)

        func makeFunction(name string) func() {
            fmt.Println("00000")
            return makeFunction2("abcef")
        }
        
        func makeFunction2(name string) func() {
            fmt.Println("11111")
            return makeFunction3("safsf")
        }
        
        func makeFunction3(name string) func() {
            fmt.Println("33333")
            return func() {
                fmt.Printf("444444")
            }
        }
        
        func main() {
            f := makeFunction("hellooo")
            f()
        }
        
        // Output: 
        00000
        11111
        33333
        444444
        

        【讨论】:

          【解决方案5】:

          原因是它只返回匿名函数。

          package main
          
          import "fmt"
          
          func makeFunction(name string) func() {
              fmt.Println("00000")
              return func(){
                  makeFunction2("abcef")()
              }
          }
          
          func makeFunction2(name string) func() {
              fmt.Println("11111")
              return func() {
                  makeFunction3("safsf")()
              }
          }
          
          func makeFunction3(name string) func() {
              fmt.Println("33333")
              return func() {
                  fmt.Printf("444444")
              }
          }
          
          func main() {
              f := makeFunction("hellooo")
              f()
          }
          

          【讨论】:

            猜你喜欢
            • 2018-03-22
            • 1970-01-01
            • 1970-01-01
            • 2016-09-08
            • 1970-01-01
            • 1970-01-01
            • 2018-06-22
            • 1970-01-01
            • 2022-01-19
            相关资源
            最近更新 更多