检查列表是否为空 (Raku)
Check if a list is empty (Raku)
常见问题解答:在 Raku 中如何检查列表是否为空?
是否有比以下更惯用的方式:
my @l = ();
say @l.elems == 0;
say @l == ();
say @l.Bool;
doc on list recommends smartmatching
say $l ~~ ();
- 你知道其他方法吗?
- 你能解释为什么
() === ()
是错误的,即使 "" === ""
是正确的:我不清楚。
建议的人中:
say @l.elems == 0;
这是一个很好的避免方法,因为它强制计算惰性列表中的所有元素(如果有标记为惰性的迭代器,这可能会导致异常,因为替代方案是 运行 直到所有内存都用完了)。
say @l == ();
这可行,但存在与上述相同的问题。 ==
运算符是数值相等的,所以它会强制双方为一个数字,然后比较它们。这也归结为 @l.elems
(通过 @l.Numeric
)。您可以将这种形式写得更便宜,如 @l == 0
,如果您真的想询问总共有多少个元素,这是最简洁的方法。
say @l.Bool;
这样更好,因为在惰性列表中,它最多只强制评估一个元素来回答问题。然而,它实际上与所问的相反:如果数组 而不是 为空,则为 True
。像这样使用 ?
和 !
前缀运算符更自然:
say ?@l; # is not empty
say !@l; # is empty
尽管通常您甚至不需要,因为 if
和 unless
之类的东西提供了布尔上下文。因此可以这样写:
if @l { } # not empty
unless @l { } # empty
这些可能是最好的方法。
至于其他建议:
say $l ~~ ();
这很好,虽然可能比 boolification 方法慢。
() === ()
is wrong even if "" === ""
is right
那是因为List
是引用类型,不是值类型。由于 ()
每次都构造一个不同的空列表,因此它们是不同的对象,因此将作为不同的对象进行比较。您可以使用 eqv
代替:
say () eqv () # True
但是不要使用它来检查列表是否为空,因为它可能过于具体。例如:
my @l; say @l eqv (); # False
my @l; say @l eqv []; # True
这是因为 ()
是 List
类型,而 my @l
声明了一个 Array
。一般来说,你不想关心那里到底是什么类型。
最后,关于这一行:
my @l = ();
()
的赋值毫无意义; my @a
已经创建了一个空 Array
。事实上,这是一种常见的代码味道,逗号 IDE 对此给出了一个微弱的警告:
常见问题解答:在 Raku 中如何检查列表是否为空? 是否有比以下更惯用的方式:
my @l = ();
say @l.elems == 0;
say @l == ();
say @l.Bool;
doc on list recommends smartmatching
say $l ~~ ();
- 你知道其他方法吗?
- 你能解释为什么
() === ()
是错误的,即使"" === ""
是正确的:我不清楚。
建议的人中:
say @l.elems == 0;
这是一个很好的避免方法,因为它强制计算惰性列表中的所有元素(如果有标记为惰性的迭代器,这可能会导致异常,因为替代方案是 运行 直到所有内存都用完了)。
say @l == ();
这可行,但存在与上述相同的问题。 ==
运算符是数值相等的,所以它会强制双方为一个数字,然后比较它们。这也归结为 @l.elems
(通过 @l.Numeric
)。您可以将这种形式写得更便宜,如 @l == 0
,如果您真的想询问总共有多少个元素,这是最简洁的方法。
say @l.Bool;
这样更好,因为在惰性列表中,它最多只强制评估一个元素来回答问题。然而,它实际上与所问的相反:如果数组 而不是 为空,则为 True
。像这样使用 ?
和 !
前缀运算符更自然:
say ?@l; # is not empty
say !@l; # is empty
尽管通常您甚至不需要,因为 if
和 unless
之类的东西提供了布尔上下文。因此可以这样写:
if @l { } # not empty
unless @l { } # empty
这些可能是最好的方法。
至于其他建议:
say $l ~~ ();
这很好,虽然可能比 boolification 方法慢。
() === ()
is wrong even if"" === ""
is right
那是因为List
是引用类型,不是值类型。由于 ()
每次都构造一个不同的空列表,因此它们是不同的对象,因此将作为不同的对象进行比较。您可以使用 eqv
代替:
say () eqv () # True
但是不要使用它来检查列表是否为空,因为它可能过于具体。例如:
my @l; say @l eqv (); # False
my @l; say @l eqv []; # True
这是因为 ()
是 List
类型,而 my @l
声明了一个 Array
。一般来说,你不想关心那里到底是什么类型。
最后,关于这一行:
my @l = ();
()
的赋值毫无意义; my @a
已经创建了一个空 Array
。事实上,这是一种常见的代码味道,逗号 IDE 对此给出了一个微弱的警告: