FAQ:在 Raku 中如何检查列表是否为空?是否有比以下更惯用的方法:
my @l = ();
say @l.elems == 0;
say @l == ();
say @l.Bool;
Run Code Online (Sandbox Code Playgroud)
say $l ~~ ();
Run Code Online (Sandbox Code Playgroud)
() === ()
即使"" === ""
是正确的,您能否解释为什么 是错误的:我对此不清楚。Jon*_*ton 11
其中建议:
say @l.elems == 0;
Run Code Online (Sandbox Code Playgroud)
这是一个很好避免的方法,因为它会强制对惰性列表中的所有元素进行评估(如果迭代器标记为惰性,则可能会导致异常,因为替代方法将一直运行,直到所有内存都用完为止)。
say @l == ();
Run Code Online (Sandbox Code Playgroud)
这有效,但具有与上述相同的问题。该==
运营商的数字平等,所以它会迫使双方一个数字,然后对它们进行比较。这也归结为@l.elems
(via. @l.Numeric
)。你可以把这个形式写成更便宜的@l == 0
,如果你真的想询问总共有多少个元素,这是最简洁的方式。
say @l.Bool;
Run Code Online (Sandbox Code Playgroud)
这更好,因为在惰性列表中,它最多只强制评估一个元素来回答问题。然而,这实际上与所问的相反:这是True
如果数组不为空。像这样使用?
和!
前缀运算符更自然:
say ?@l; # is not empty
say !@l; # is empty
Run Code Online (Sandbox Code Playgroud)
尽管很多时候你甚至都不需要做的是,因为事情好像if
并unless
提供布尔环境。因此可以写:
if @l { } # not empty
unless @l { } # empty
Run Code Online (Sandbox Code Playgroud)
这些可能是最好的方法。
至于其他建议:
say $l ~~ ();
Run Code Online (Sandbox Code Playgroud)
这很好,虽然可能比布尔化方法慢。
() === ()
即使"" === ""
是对的也是错的
那是因为List
是引用类型,而不是值类型。由于()
每次都构造一个不同的空列表,因此它们是不同的对象,因此将比较为不相同。您可以eqv
改用:
say () eqv () # True
Run Code Online (Sandbox Code Playgroud)
但是不要用它来检查列表是否为空,因为它可能过于具体。例如:
my @l; say @l eqv (); # False
my @l; say @l eqv []; # True
Run Code Online (Sandbox Code Playgroud)
这是因为()
is 是类型List
,而 whilemy @l
声明了一个Array
. 通常,您不想关心真正存在的类型。
最后,关于这一行:
my @l = ();
Run Code Online (Sandbox Code Playgroud)
的赋值()
毫无意义;my @a
已经创建了一个空的Array
. 事实上,这是一种很常见的代码味道,Comma IDE 对此给出了一个微弱的警告: