其中建议的:
say @l.elems == 0;
这是一个很好的避免方法,因为它强制评估惰性列表中的所有元素(如果有标记为惰性的迭代器,这可能会导致异常,因为替代方案将一直运行,直到所有内存耗尽)。
say @l == ();
这可行,但有与上面相同的问题。这==
运算符是数字相等,因此它将强制两边都为数字,然后比较它们。这也归结为@l.elems
(via. @l.Numeric
)。你可以更便宜地写这个表格@l == 0
,如果您确实想询问总共有多少个元素,这是最好的方法。
say @l.Bool;
这更好,因为在惰性列表中,它最多只强制评估一个元素来回答问题。然而,这实际上与所问的相反:这是True
如果数组是not空的。使用更自然?
and !
前缀运算符如下:
say ?@l; # is not empty
say !@l; # is empty
虽然很多时候你甚至不需要做that,因为像这样的事情if
and unless
提供布尔上下文。因此可以这样写:
if @l { } # not empty
unless @l { } # empty
这些可能是最好的方法。
至于其他建议:
say $l ~~ ();
这很好,尽管可能比布尔化方法慢。
() === ()
是错误的,即使"" === ""
是对的
那是因为List
是引用类型,而不是值类型。自从()
每次都会构造一个不同的空列表,它们是不同的对象,因此将作为不相同进行比较。您可以使用eqv
反而:
say () eqv () # True
但不要用它来检查列表是否为空,因为它可能过于具体。例如:
my @l; say @l eqv (); # False
my @l; say @l eqv []; # True
这是因为()
属于类型List
, while my @l
声明一个Array
。一般来说,您不想关心到底是什么类型。
最后,关于这一行:
my @l = ();
的分配()
毫无意义;my @a
已经创建了一个空的Array
。事实上,这是一种很常见的代码味道,Comma IDE 对此给出了弱警告: