为什么Go不允许嵌套函数声明(函数内部的函数)?

时间:2014-02-22 22:41:56

标签: function go declaration

编辑:如果不清楚我在问什么:不允许嵌套函数声明会减轻哪些问题?

Lambdas按预期工作:

func main() {
    inc := func(x int) int { return x+1; }
}

但是,不允许声明中的以下声明:

func main() {
    func inc(x int) int { return x+1; }
}

为什么不允许使用嵌套函数?

6 个答案:

答案 0 :(得分:45)

我认为有三个理由说明为什么不允许使用这个明显的功能

  1. 这会使编译器稍微复杂化。目前,编译器知道所有功能都在顶层。
  2. 它会产生一类新的程序员错误 - 你可以重构一些东西并意外地嵌套一些函数。
  3. 对函数和闭包使用不同的语法是一件好事。制作一个闭包可能比制作一个函数更昂贵,所以你应该知道你正在这样做。
  4. 这些只是我的观点 - 我还没有看到语言设计师的正式声明。

答案 1 :(得分:21)

  

Frequently Asked Questions (FAQ)

     

Why does Go not have feature X?

     

每种语言都包含新颖的功能,并省略了某人的喜爱   特征。 Go的设计着眼于节目的快节奏,速度   编辑,概念的正交性和支持的需要   并发和垃圾收集等功能。你的最爱   功能可能会丢失,因为它不适合,因为它会影响   编译速度或设计的清晰度,或因为它会使   基本系统模型太难了。

     

如果您对Go缺少功能X感到困扰,请原谅我们   调查Go确实具有的功能。你可能会发现他们   因缺乏X而以有趣的方式弥补。

添加嵌套函数的复杂性和费用是什么?如果没有嵌套函数,你不能做什么?等等。

答案 2 :(得分:20)

当然可以。您只需将它们分配给变量:

func main() {
    inc := func(x int) int { return x+1; }
}

答案 3 :(得分:10)

Here's a way to implement nested functions and functions within nested functions

package main

    import "fmt"

    func main() {
        nested := func() {
            fmt.Println("I am nested")

            deeplyNested := func() {
                fmt.Println("I am deeply nested")
            }

            deeplyNested()
        }

        nested()
    }

答案 4 :(得分:0)

在Go中允许嵌套函数。您只需要将它们分配给外部函数中的局部变量,然后使用这些变量进行调用即可。

示例:

func outerFunction(iterations int, s1, s2 string) int {
    someState := 0
    innerFunction := func(param string) int {
        // Could have another nested function here!
        totalLength := 0
        // Note that the iterations parameter is available
        // in the inner function (closure)
        for i := 0; i < iterations; i++) {
            totalLength += len(param)
        }
        return totalLength
    }
    // Now we can call innerFunction() freely
    someState = innerFunction(s1)
    someState += innerFunction(s2)
    return someState
}
myVar := outerFunction(100, "blah", "meh")

内部函数通常对于本地goroutine很方便:

func outerFunction(...) {
    innerFunction := func(...) {
        ...
    }
    go innerFunction(...)
}

答案 5 :(得分:-2)

您只需在最后添加()即可立即拨打电话。

func main() {
    func inc(x int) int { return x+1; }()
}

编辑:不能有函数名...所以它只是一个lambda函数立即被调用:

func main() {
    func(x int) int { return x+1; }()
}