为什么不能同时分配和调用块?

时间:2012-08-19 03:36:38

标签: objective-c objective-c-blocks

以下代码编译:

^{}();

这个编译:

void (^x)();
(x = ^{})();

但这不是:

(void (^x)() = ^{})();

我得到的错误是Expected ')'。这是llvm或其他什么的错误吗?它完全阻止我假装Objective-C是JavaScript。

2 个答案:

答案 0 :(得分:6)

这在C语言中没有意义。为了了解原因,让我们从头开始构建声明。

首先,我们将使用x的工作声明:

void (^x)();

现在让我们在同一个语句中初始化它:

void (^x)() = ^{};

到目前为止一直很好 - x已使用正确的块初始化。那么现在让我们调用x。但是()去哪儿了?当然,我们需要在块值表达式之后立即放置()。但是,在C中,声明是语句,而不是表达式

(void (^x)() = ^{})();

没有意义。 ()可以去的唯一地方是^{}

之后
void (^x)() = ^{}();

^{}()的类型为void,而不是void (^)()类型。

总结一下:你不能声明一个块变量并同时调用它。你必须声明并初始化变量,然后调用它

void (^x)() = ^{};
x();

或声明它然后分配并调用它

void (^x)();
(x = ^{})();

或者只是分开所有三个:

void (^x)();
x = ^{};
x();

作为最后的想法,让我们说同时声明和调用块是可取的。如果我们决定允许(void (^x)() = ^{})();之类的代码,那么为了保持一致性,我们还必须允许代码++(void x = 4);(void x = 1) + (void y = 2);。我希望你会同意这些在C中看起来很奇怪。

答案 1 :(得分:3)

作为类比,请考虑:

编译:

if (42) { }

这个编译:

int x;
if (x = 42) { }

但这不是:

if (int x = 42) { }