在 Go 中不允许嵌套函数声明可以缓解哪些问题?

Lambdas 的工作正如预期的那样:

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

但不得在声明内作出下列声明:

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

为什么不允许嵌套函数?

64119 次浏览

常见问题

为什么 Go 没有特性 X?

每一种语言都包含着新奇的特点,并且忽略了某些人的最爱 围棋的设计着眼于编程的合理性、速度 汇编,正交的概念,以及需要支持 特性,如并发和垃圾收集 特征可能会丢失,因为它不适合,因为它影响 编译速度或设计的清晰度,或因为它会使 基本系统模型太难。

如果 Go 缺少 X 特性让您感到困扰,请原谅我们 研究围棋确实具有的特点。你可能会发现 以有趣的方式补偿 X 的缺失。

添加嵌套功能的复杂性和费用如何解释?没有嵌套函数就无法执行的操作是什么?等等。

我认为有三个原因为什么这个明显的特征是不允许的

  1. 这会使编译器稍微复杂一些,因为目前编译器知道所有的函数都在顶层。
  2. It would make a new class of programmer error - you could refactor something and accidentally nest some functions.
  3. 对函数和闭包使用不同的语法是一件好事。创建一个闭包可能比创建一个函数更昂贵,因此您应该知道您正在这样做。

这些只是我的观点——我还没有看到语言设计者的正式声明。

下面是一种在嵌套函数中实现嵌套函数和函数的方法

package main


import "fmt"


func main() {


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


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


deeplyNested()
}


nested()
}

您只需要通过将 ()添加到末尾来立即调用它。

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

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

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

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(...)
}