Raku中for循环内用when的优雅写法:兼顾可读变量名且无需given?
解决Raku中
for循环绑定命名变量后when失效的问题 在处理XML节点时,我们可以写出这样简洁的代码(这里的$elem是XML::Element类型,类型不影响问题本身):
for $elem.nodes { when XML::Element { ... } when XML::Text { ... } ... default { note qq{Ignoring unknown XML node "$_".} } }
这种写法虽然简洁,但$_作为默认变量,可读性较差。如果想换成更清晰的命名变量(比如$child),直接写成下面的形式会失效:
for $elem.nodes -> $child { when XML::Element { ... } when XML::Text { ... } ... default { note qq{Ignoring unknown XML node "$child".} } }
原因是当for循环使用签名绑定变量时,默认变量$_不会被自动赋值,而when默认匹配的是$_,所以这些条件分支不会生效。通常的解决办法是套一层given,但会增加冗余和缩进:
for $elem.nodes -> $child { given $child { when XML::Element { ... } when XML::Text { ... } ... default { note qq{Ignoring unknown XML node "$child".} } } }
其实有两种更简洁的方式,既能保留命名变量的可读性,又不用嵌套given:
方法一:手动将命名变量赋值给$_
在循环块开头,把绑定的$child赋值给$_,这样when就能正常匹配,同时在需要的地方依然可以使用$child这个清晰的变量名:
for $elem.nodes -> $child { $_ = $child; when XML::Element { ... } when XML::Text { ... } ... default { note qq{Ignoring unknown XML node "$child".} } }
方法二:给when指定匹配目标
Raku的when语句支持通过后缀given直接指定匹配对象,这样就不需要依赖$_了:
for $elem.nodes -> $child { when XML::Element { ... } given $child; when XML::Text { ... } given $child; ... default { note qq{Ignoring unknown XML node "$child".} } }
这种方式需要给每个when添加后缀,但也能达到避免嵌套given的目的。
内容的提问来源于stack exchange,提问作者VZ.
相关产品推荐
相关产品推荐

