3

ブロックスコープで動作する関数を作成することは可能ですか?そのような

明確にするために編集

enum { cannot, must };
int it(enum modal verb);

describe(fx) {
    context("some context") {
        it(must) { /* Some test that returns an int to it() */ };
    }
}

私はこれが可能だとは思わないので、私ができる次善の策は何ですか?

4

2 に答える 2

6

これは私には Smalltalk や Ruby のように見え、関数にクロージャ(ブロックと呼ばれることもあります) を渡したいと思わせます。これは、C のさまざまな拡張機能で可能であり、回避策もあります。

たとえば、リストを反復処理したい場合があります。

{
    // this does not actually work, sorry
    iterate(list) { |i| -> printf("%d\n", i); }
}

C に対する Apple の拡張機能を使用している場合は、「ブロック」と呼ばれるものを使用できます。

{
    // Apple only
    iterate(list, ^(int i) { printf("%d\n", i); });
}

コールバックを書くこともできます。

static void my_callback(int i) { printf("%d\n", i); }

...
{
    iterate(list, my_callback);
}

コールバックは、他の関数のスコープ内の変数にアクセスできないため、変数を共有する方法を考え出す必要があります。

また、GCC にはネストされた関数があります。これらは、Apple の「ブロック」拡張機能と同様にスコープ変数にアクセスできます。

{
    // GCC only
    void callback(int i) { printf "%d\n", i); }
    iterate(list, callback);
}

これを頻繁に行いたい場合は、C 以外の言語に切り替えることで、頭痛の種を大幅に減らすことができます。C は、高階プログラミングにはあまり適していません。

于 2012-07-25T06:25:56.227 に答える
0

あなたが何を望んでいるのかよくわかりませんが、おそらくGCCのネストされた関数拡張があなたのニーズに答えます。これは非標準の拡張機能であることに注意してください (また、一部のコンパイラでは提供されていません)。

C 関数は (悲しいことに)クロージャーではないことに注意してください。これが関数型言語 (Ocaml、Haskell、Scheme など) に切り替える理由です。

于 2012-07-25T05:59:05.493 に答える