无法将if语句分配给变量

时间:2020-10-20 05:07:09

标签: raku

这里的问题是我不太了解控制流中的语句和块之间的区别。

寻找三元运算符,我可以使用它来分配变量。但这是一个运算符,所以就像应用一个函数一样,不是吗?

> my $variable = True ?? 34 !! 42;
34 

因为raku文档中说:

if documentation

if

要有条件地运行代码块,请使用if,后跟一个 健康)状况。条件,即表达式,将立即求值 if前的语句之后。附加到 仅当条件表示True时,才会评估条件 被逼到布尔。与某些语言不同,该条件不必 请加上括号,而必须在该块周围使用{}

do documentation

do

运行不能成为独立语句的块的最简单方法是在其前面写入do

所以这在两种情况下都应该起作用:

> 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确实没有运行该块...或者这里的真正问题是什么?

1 个答案:

答案 0 :(得分:12)

TL; DR:实际差异是陈述表达式之间的差异,而不是陈述 block do是创建表达式的语句前缀。


if实际上会创建一条语句(Raku中运行的所有语句),但是它不是expressiondo是语句前缀,它的作用是将语句转换为表达式。

但是,if并不是真正可以分配给变量或处理的一流函数。每当您发现某种语法片段(例如{或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是客体,一等公民。您可以使用它们,应用它们,然后将它们传递出去。

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语句打印输出,它还会产生可以分配的结果。所有这三行也是语句,实际上也是表达式。

但是,某些控制结构不会创建表达式。

其他一些人这样做; for创建一个表达式; while不会。

if就是一个例子。他们不会产生结果。您将它们用于副作用:运行一个语句(如果为true)或另一个(如果不是)。您可以像上面一样将它们变成一个块,然后传递它们。或者,您可以在它们前面加上do,使它们产生一个一次性的结果,然后可以使用它。

因此,这在很大程度上取决于您的实际用例。您可以将if语句括在花括号中并创建一个块;或者您可以简单地使用结果创建表达式。或者您可能只想将其用于副作用,什么也不做。

相关问题