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

Ans*_*ala 3 objective-c objective-c-blocks

以下代码编译:

^{}();
Run Code Online (Sandbox Code Playgroud)

这编译:

void (^x)();
(x = ^{})();
Run Code Online (Sandbox Code Playgroud)

但这不是:

(void (^x)() = ^{})();
Run Code Online (Sandbox Code Playgroud)

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

Ken*_*nde 6

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

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

void (^x)();
Run Code Online (Sandbox Code Playgroud)

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

void (^x)() = ^{};
Run Code Online (Sandbox Code Playgroud)

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

(void (^x)() = ^{})();
Run Code Online (Sandbox Code Playgroud)

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

void (^x)() = ^{}();
Run Code Online (Sandbox Code Playgroud)

^{}()有类型void,而不是类型void (^)().

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

void (^x)() = ^{};
x();
Run Code Online (Sandbox Code Playgroud)

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

void (^x)();
(x = ^{})();
Run Code Online (Sandbox Code Playgroud)

或者只是分开所有三个:

void (^x)();
x = ^{};
x();
Run Code Online (Sandbox Code Playgroud)

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