4

すべてのコマンドをマップに含めて、コマンドからジョブを実行する関数 (単なる標準ディスパッチ テーブル) にマップしたいと考えています。私は次のコードから始めました:

package main

import "fmt"

func hello() {
    fmt.Print("Hello World!")
}

func list() {
    for key, _ := range whatever {
        fmt.Print(key)
    }
}

var whatever = map[string](func()) {
    "hello": hello,
    "list": list,
}

ただし、関数と構造体の間に再帰参照があるため、コンパイルに失敗します。関数を前方宣言しようとすると、関数が定義されているときに再定義に関するエラーで失敗し、マップはトップレベルにあります。このような構造を定義し、関数を使用せずに最上位で初期化するにはどうすればよいでしょうか。init()

言語の定義に適切な説明がありません。

  • 存在する前方参照は「外部」関数用であり、関数を前方宣言しようとするとコンパイルされません。
  • 変数を前方宣言する方法も見つかりません。

更新:プログラムの起動時や関数内で変数を明示的に設定する必要のないソリューションを探していますinit()。それが可能かどうかはわかりませんが、私が知っているすべての同等の言語で機能します。

更新 2: FigmentEngineは、以下の回答として提供したアプローチを提案しました。再帰型を処理でき、すべてのコマンドのマップの静的初期化も可能です。

4

3 に答える 3

2

すでにお気づきかもしれませんが、Go の仕様には次のように記載されています (強調):

A の初期化子が B に依存する場合、A は B の後に設定されます。依存関係の分析は、初期化される項目の実際の値には依存せず、ソースでのそれらの外観のみに依存します。A の値が B の言及を含むか、初期化子が B を言及する値を含むか、または B を言及する関数を再帰的に言及する場合、 A は B に依存します。このような依存関係が循環している場合はエラーです。

だから、いいえ、あなたがやろうとしていることをすることは不可能です. Issue 1817でこの問題について言及されており、Russ Cox は Go のアプローチは時として過度に制限的である可能性があると述べています。しかし、それは明確で明確に定義されており、回避策が利用可能です。

したがって、それを回避する方法は、依然として を使用することinit()です。ごめん。

于 2013-10-28T11:27:36.617 に答える
0

を使用する前に、関数内にマップを入力するだけlist()です。そのよう

申し訳ありませんが、あなたが「なしinit()」と書いているのを見ませんでした。それは不可能です。

于 2013-10-28T10:58:25.397 に答える