无法将 if 语句分配给变量
Cannot assign an if statement to a variable
这里的问题是我不太了解控制流中语句和块之间的区别。
查看三元运算符,我可以用它来分配变量。但这是一个运算符,所以它就像应用一个函数——不是吗?
> my $variable = True ?? 34 !! 42;
34
因为在 raku 文档中说:
if
To conditionally run a block of code, use an if
followed by a
condition. The condition, an expression, will be evaluated immediately
after the statement before the if
finishes. The block attached to the
condition will only be evaluated if the condition means True
when
coerced to Bool. Unlike some languages the condition does not have to
be parenthesized, instead the {
and }
around the block are mandatory:
do
The simplest way to run a block where it cannot be a stand-alone statement is by writing do
before it:
所以这应该适用于两种情况:
> my $variable = do {34};
34
> my $variable = if True {34;} else {43;}
===SORRY!===
Word 'if' interpreted as a listop; please use 'do if' to introduce the statement control word
------> my $variable = if⏏ True {34;} else {43;}
Unexpected block in infix position (two terms in a row)
------> my $variable = if True⏏ {34;} else {43;}
如错误中所述,我需要添加 do
:
> my $variable = do if True {34;} else {43;}
34
所以 if
确实没有 运行 块...或者这里真正的问题是什么?
TL;DR:实际区别在于 statement 和 expression,而不是 statement 阻止。 do
是创建表达式的语句前缀。
if
实际上创建了一个语句(在 Raku 中任何 运行 都是),但是,它不是 expression。 do
是一个语句前缀,它的作用是把语句变成表达式。
但是,if
并不是真正的 first-class 函数,您可以将其分配给变量或处理。每当你发现诸如那个(或 for
之类的语法片段时,你需要在它们前面加上 do
前缀以“表达”它们。
say &say.^name;# OUTPUT: «Sub» say &do.^name; # OUTPUT: «===SORRY!=== Error while compiling <tmp>Undeclared routine:...
say &if.^name; # OUTPUT: «===SORRY!=== Error while compiling <tmp>Undeclared routine: if used at line 1»
所以 if
本身不会创建块,它不会创建表达式,它只是创建一个语句。如果你想让它真正变成一个表达式,你需要在它前面加上 do
。但是,它确实 运行 它后面的块。
让我们回到最初的问题、陈述和方块。 Blocks 是物体,first-class 是公民。您可以使用它们、应用它们、传递它们。
my &ifs = { if $_ {34} else {43}};
ifs(True).say; # OUTPUT: «34»
语句是一次性块,您只需 运行。在某些情况下,它们也是表达式:它们产生一个结果,然后您可以对其进行赋值。
my &ifs = { if $_ {34} else {43}};
my $result = ifs(True).say; # OUTPUT: «34»
say $result; # OUTPUT: «True»
ifs(True).say
语句打印输出,它也产生一个可以赋值的结果。这三行也是语句,实际上也是表达式。
但是,某些控制结构不创建表达式。
Some others do; for
creates a expression; while
does not.
if
就是一个例子。他们不产生结果。您将它们用于副作用:运行ning 一个语句(如果为真)或另一个(如果不是)。你可以像上面那样把它们变成一个块,然后传递它们。或者您可以在它们前面加上 do
并使它们产生一次性结果,然后您可以使用它。
所以这在很大程度上取决于您的实际用例。您可以用花括号将 if 语句括起来并创建一个块;或者您可以简单地使用创建表达式的结果。或者您可能只想将它用于副作用,什么都不做。
这里的问题是我不太了解控制流中语句和块之间的区别。
查看三元运算符,我可以用它来分配变量。但这是一个运算符,所以它就像应用一个函数——不是吗?
> my $variable = True ?? 34 !! 42;
34
因为在 raku 文档中说:
if
To conditionally run a block of code, use an
if
followed by a condition. The condition, an expression, will be evaluated immediately after the statement before theif
finishes. The block attached to the condition will only be evaluated if the condition meansTrue
when coerced to Bool. Unlike some languages the condition does not have to be parenthesized, instead the{
and}
around the block are mandatory:
do
The simplest way to run a block where it cannot be a stand-alone statement is by writing
do
before it:
所以这应该适用于两种情况:
> my $variable = do {34};
34
> my $variable = if True {34;} else {43;}
===SORRY!===
Word 'if' interpreted as a listop; please use 'do if' to introduce the statement control word
------> my $variable = if⏏ True {34;} else {43;}
Unexpected block in infix position (two terms in a row)
------> my $variable = if True⏏ {34;} else {43;}
如错误中所述,我需要添加 do
:
> my $variable = do if True {34;} else {43;}
34
所以 if
确实没有 运行 块...或者这里真正的问题是什么?
TL;DR:实际区别在于 statement 和 expression,而不是 statement 阻止。 do
是创建表达式的语句前缀。
if
实际上创建了一个语句(在 Raku 中任何 运行 都是),但是,它不是 expression。 do
是一个语句前缀,它的作用是把语句变成表达式。
但是,if
并不是真正的 first-class 函数,您可以将其分配给变量或处理。每当你发现诸如那个(或 for
之类的语法片段时,你需要在它们前面加上 do
前缀以“表达”它们。
say &say.^name;# OUTPUT: «Sub» say &do.^name; # OUTPUT: «===SORRY!=== Error while compiling <tmp>Undeclared routine:...
say &if.^name; # OUTPUT: «===SORRY!=== Error while compiling <tmp>Undeclared routine: if used at line 1»
所以 if
本身不会创建块,它不会创建表达式,它只是创建一个语句。如果你想让它真正变成一个表达式,你需要在它前面加上 do
。但是,它确实 运行 它后面的块。
让我们回到最初的问题、陈述和方块。 Blocks 是物体,first-class 是公民。您可以使用它们、应用它们、传递它们。
my &ifs = { if $_ {34} else {43}};
ifs(True).say; # OUTPUT: «34»
语句是一次性块,您只需 运行。在某些情况下,它们也是表达式:它们产生一个结果,然后您可以对其进行赋值。
my &ifs = { if $_ {34} else {43}};
my $result = ifs(True).say; # OUTPUT: «34»
say $result; # OUTPUT: «True»
ifs(True).say
语句打印输出,它也产生一个可以赋值的结果。这三行也是语句,实际上也是表达式。
但是,某些控制结构不创建表达式。
Some others do;
for
creates a expression;while
does not.
if
就是一个例子。他们不产生结果。您将它们用于副作用:运行ning 一个语句(如果为真)或另一个(如果不是)。你可以像上面那样把它们变成一个块,然后传递它们。或者您可以在它们前面加上 do
并使它们产生一次性结果,然后您可以使用它。
所以这在很大程度上取决于您的实际用例。您可以用花括号将 if 语句括起来并创建一个块;或者您可以简单地使用创建表达式的结果。或者您可能只想将它用于副作用,什么都不做。