web-dev-qa-db-ja.com

Goがネストされた関数宣言(関数内の関数)を許可しないのはなぜですか?

編集:質問の内容が明確でない場合:ネストされた関数宣言を許可しないことで軽減される問題は何ですか? =

ラムダは期待どおりに動作します:

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

ただし、宣言内の次の宣言は許可されていません。

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

ネストされた関数が許可されない理由は何ですか?

67
corazza

この明らかな機能が許可されない理由は3つあると思います

  1. コンパイラが少し複雑になります。現時点では、コンパイラはすべての関数が最上位にあることを知っています。
  2. 新しいクラスのプログラマーエラーが発生します-何かをリファクタリングして、誤っていくつかの関数をネストすることができます。
  3. 関数とクロージャーに異なる構文を使用するのは良いことです。クロージャを作成することは、関数を作成するよりも潜在的に費用がかかるため、あなたがそれを行っていることを知っておく必要があります。

しかし、これらは私の意見です-言語設計者からの公式な宣言は見ていません。

45
Nick Craig-Wood

確かにそうです。それらを変数に割り当てる必要があります。

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

よくある質問(FAQ)

Goに機能Xがないのはなぜですか

すべての言語には新しい機能が含まれており、誰かのお気に入りの機能は省略されています。 Goは、プログラミングの容易さ、コンパイルの速度、概念の直交性、および並行性やガベージコレクションなどの機能をサポートする必要性に着目して設計されました。お気に入りの機能は、適合しないため、コンパイル速度やデザインの明瞭さに影響するため、または基本的なシステムモデルが非常に難しくなるため、欠落している可能性があります。

Goに機能Xが欠けていることが気になる場合は、ご容赦ください。Goの機能を調査してください。 Xがないことを興味深い方法で補っていることがわかるかもしれません。

ネストされた関数を追加する複雑さと費用を正当化するものは何ですか?入れ子関数なしではできないことを、ヤウは何をしたいのですか?など。

22
peterSO

ネストされた関数とネストされた関数内の関数を実装する方法です

package main

    import "fmt"

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

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

            deeplyNested()
        }

        nested()
    }
12
Koala3

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")

内部関数は多くの場合、ローカルゴルーチンに便利です。

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