我在某处找到了该运算符,当我在https://docs.raku.org/routine/andthen
中查找它时,我发现了这个:
#!/bin/env raku\nsub load-data\n{\n rand > .5 or return; # simulated load data failure; return Nil\n (rand > .3 ?? \'error\' !! \'good data\') xx 10 # our loaded data \n}\n\nload-data.first: /good/ andthen say "$_ is good";\n# OUTPUT: \xc2\xab(good data is good)\xe2\x90\xa4\xc2\xbb \n\nload-data() andthen .return; # return loaded data, if it\'s defined \ndie "Failed to load data!!"; \n
Run Code Online (Sandbox Code Playgroud)\n那么,当应用于 subs 时,它是如何.first
工作.return
的?\n我以前从未见过这样的事情。
Sil*_*olo 11
那么,应用于 subs 时如何工作
.first
?.return
事实并非如此。您没有调用.first
或 .return
调用某个Sub
对象。
当 Raku 中的子例程不带参数出现时,就会调用它。因此,只需编写load-data
其自己的调用 load-data
即可,就像添加括号一样。(注意:如果你想获取子例程对象本身,你使用一个&
印记,&load-data
子例程对象也是如此)所以这个
load-data.first: /good/ andthen say "$_ is good";
Run Code Online (Sandbox Code Playgroud)
相当于更熟悉的类似 Python 的语法中的类似内容。
load_data().first("good") and say(...)
Run Code Online (Sandbox Code Playgroud)
首先,load-data
被称为。它返回数据Nil
或数据列表。现在first
叫就行了。
返回智能匹配的列表的第一项,当没有值匹配时
$matcher
返回。Nil
可选的命名参数:end
指示搜索应该从列表的末尾开始,而不是从开头开始。
您已将其称为load-data.first: /good/
,因此它将返回正则表达式/good/
匹配的列表的第一个元素,否则返回Nil
。
andthen
类似于&&
,除了在&&
检查真实性(通过布尔上下文)时,andthen
通过 multi 方法检查定义性defined
。像 和 失败这样的对象Nil
是未定义的,而大多数“普通”对象(例如数字和字符串)是定义的。特别是,像零或空字符串这样传统上“假”的东西仍然被定义。与 一样&&
,andthen
短路,因此如果左侧未定义,则右侧永远不会计算。
最后,还有一个使这条线能够工作的怪癖。andthen
旨在处理这个确切的用例:执行第 1 件事,如果该事件成功,则执行第 2 件事。通常,第 2 件事取决于第 1 件事的结果。因此,andthen
将左侧的结果分配给特殊变量$_
在评估右侧时。实在是太拗口了,我们就写出来吧。x andthen y
执行以下操作。
x
。x
未定义,则停止。我们完成了。返回x
。$_
为 的结果x
。y
(使用$_
集合)并返回它。所以,把这一切都考虑进去……
load-data.first: /good/ andthen say "$_ is good";
Run Code Online (Sandbox Code Playgroud)
加载数据,找到加载数据中与正则表达式匹配的第一个元素,如果存在,则将其打印出来。
现在让我们看一下第二个例子。对于这个,您还需要了解另一个有趣的小语法糖。一般来说,语句开头的点带有隐含的$_
. 因此.say
等价于$_.say
, 等价于say($_:)
, 在方法解析为 后求值say($_)
。
不管你信不信,它return
是一个子程序。严重地。它不是一个关键字;而是一个关键字。这是一个潜艇。&return.WHAT
立即在您的 REPL 中进行评估。它会说(Sub)
。
load-data() andthen .return;
die "Failed to load data!!";
Run Code Online (Sandbox Code Playgroud)
load-data
被调用,如果它返回任何定义的值,则该定义的值将被分配给$_
. 然后.return
发生,这相当于$_.return
(最终)成为return($_)
。如果定义了该值,它将从函数返回,并且第二行永远不会运行。如果没有,我们die
会提供相应的错误消息。
请注意,在这种情况下实际上需要括号。如果我们写
load-data andthen .return;
Run Code Online (Sandbox Code Playgroud)
然后 Raku 尝试解释为andthen .return
参数并load-data
抱怨不andthen
存在调用的子例程。它认为我们的意思是
load-data(andthen(.return));
Run Code Online (Sandbox Code Playgroud)
总而言之,Raku 是一个装满语法糖的大袋子,包裹在来自地狱第六圈的解析器中,它对空格和上下文敏感,其结果是一种真正美丽的语言。