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

huangapple go评论85阅读模式
英文:

What are the problems that are mitigated by not allowing nested function declarations in Go?

问题

嵌套函数不被允许的原因是什么?

英文:

Lambdas work as expected:

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

However, the following declaration inside a declaration is not allowed:

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

For what reason are nested functions not allowed?

答案1

得分: 74

我认为有三个原因导致这个明显的特性不被允许:

  1. 这会稍微复杂化编译器。目前编译器知道所有函数都在顶层。
  2. 这会引入一种新的程序员错误类型——你可能会重构某些内容并意外地嵌套一些函数。
  3. 函数和闭包具有不同的语法是一件好事。创建闭包的成本可能比创建函数更高,所以你应该知道自己在做什么。

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

英文:

I think there are 3 reasons why this obvious feature isn't allowed

  1. It would complicate the compiler slightly. At the moment the compiler knows all functions are at the top level.
  2. It would make a new class of programmer error - you could refactor something and accidentally nest some functions.
  3. Having a different syntax for functions and closures is a good thing. Making a closure is potentially more expensive than making a function so you should know you are doing it.

Those are just my opinions though - I haven't seen an official pronouncement from the language designers.

答案2

得分: 29

【常见问题解答(FAQ)】
为什么Go语言没有X功能?

每种语言都包含新颖的功能,并省略了某些人喜欢的功能。Go语言的设计考虑了编程的便利性、编译速度、概念的正交性以及支持并发和垃圾回收等功能的需求。你喜欢的功能可能因为不适合、影响编译速度或设计的清晰度,或者会使基本系统模型过于复杂而被省略。

如果你对Go语言缺少X功能感到困扰,请原谅我们,并了解Go语言所具有的功能。你可能会发现它们以有趣的方式弥补了缺少X功能的不足。

什么样的情况能够证明增加嵌套函数的复杂性和开销是合理的?你想做什么而不能在没有嵌套函数的情况下实现?等等。

英文:

> Frequently Asked Questions (FAQ)
>
> Why does Go not have feature X?
>
> Every language contains novel features and omits someone's favorite
> feature. Go was designed with an eye on felicity of programming, speed
> of compilation, orthogonality of concepts, and the need to support
> features such as concurrency and garbage collection. Your favorite
> feature may be missing because it doesn't fit, because it affects
> compilation speed or clarity of design, or because it would make the
> fundamental system model too difficult.
>
> If it bothers you that Go is missing feature X, please forgive us and
> investigate the features that Go does have. You might find that they
> compensate in interesting ways for the lack of X.

What would justify the complexity and expense of adding nested functions? What do yau want to do that you can't do without nested functions? Et cetera.

答案3

得分: 21

以下是实现嵌套函数和嵌套函数中的函数的一种方法:

package main

import "fmt"

func main() {
    nested := func() {
        fmt.Println("我是嵌套函数")

        deeplyNested := func() {
            fmt.Println("我是深度嵌套函数")
        }

        deeplyNested()
    }

    nested()
}

你可以在这里查看代码。

英文:

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

得分: 13

嵌套函数在Go语言中是允许的。你只需要将它们赋值给外部函数的局部变量,并使用这些变量来调用它们。

示例:

func outerFunction(iterations int, s1, s2 string) int {
    someState := 0
    innerFunction := func(param string) int {
        // 这里也可以有另一个嵌套函数!
        totalLength := 0
        // 注意,iterations参数在内部函数(闭包)中是可用的
        for i := 0; i < iterations; i++ {
            totalLength += len(param)
        }
        return totalLength
    }
    // 现在我们可以自由地调用innerFunction()
    someState = innerFunction(s1)
    someState += innerFunction(s2)
    return someState
}
myVar := outerFunction(100, "blah", "meh")

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

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

Nested functions are allowed in Go. You just need to assign them to local variables within the outer function, and call them using those variables.

Example:

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 &lt; iterations; i++) {
            totalLength += len(param)
        }
        return totalLength
    }
    // Now we can call innerFunction() freely
    someState = innerFunction(s1)
    someState += innerFunction(s2)
    return someState
}
myVar := outerFunction(100, &quot;blah&quot;, &quot;meh&quot;)

Inner functions are often handy for local goroutines:

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

答案5

得分: -1

你只需要在末尾添加(),立即调用它。

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

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

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

You just have to call it immediately by adding () to the end.

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

Edit: cannot have function name...so it's just a lambda func getting called right away:

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

huangapple
  • 本文由 发表于 2014年2月23日 06:41:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/21961615.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定