【问题标题】:Check if a list is empty (Raku)检查列表是否为空(Raku)
【发布时间】:2020-03-25 22:17:12
【问题描述】:

FAQ:在 Raku 中如何检查列表是否为空? 还有比这更惯用的方法吗:

my @l = ();
say @l.elems == 0;
say @l == ();
say @l.Bool;

doc on list推荐smartmatching

say $l ~~ ();
  1. 你知道其他方法吗?
  2. 即使"" === "" 是正确的,您能否解释为什么() === () 是错误的:我不清楚。

【问题讨论】:

    标签: raku


    【解决方案1】:

    建议的人中:

    say @l.elems == 0;
    

    这是一个很好的避免,因为它强制评估惰性列表中的所有元素(如果存在标记为惰性的迭代器,这可能会导致异常,因为替代方案将一直运行直到所有内存耗尽)。

    say @l == ();
    

    这可行,但有与上述相同的问题。 == 运算符是数字相等,因此它将强制双方为一个数字,然后比较它们。这也归结为@l.elems(通过。@l.Numeric)。你可以把这个表单写成@l == 0,这样更便宜,如果你真的想询问总共有多少个元素,这是最简洁的方法。

    say @l.Bool;
    

    这更好,因为在惰性列表中,它最多只强制评估一个元素来回答问题。但是,它实际上与所要求的相反:如果数组 not 为空,则为 True。像这样使用?! 前缀运算符更自然:

    say ?@l; # is not empty
    say !@l; # is empty
    

    虽然您通常甚至不需要这样做,因为像 ifunless 这样的东西提供了一个布尔上下文。因此可以这样写:

    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 类型,而my @l 声明了Array。一般来说,您不需要关心真正存在的类型。

    最后,关于这一行:

    my @l = ();
    

    () 的赋值是没有意义的; my @a 已经创建了一个空的 Array。事实上,Comma IDE 对此给出了一个弱警告:

    【讨论】:

    • 我们不要忘记“@a ~~ Empty”,它似乎也适用于 ==,尽管这可能是因为两者都强制数字为 0。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-20
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 2010-09-07
    相关资源
    最近更新 更多