检查列表是否为空 (Raku) [英] Check if a list is empty (Raku)

查看:45
本文介绍了检查列表是否为空 (Raku)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

FAQ:在 Raku 中如何检查列表是否为空?是否有比以下更惯用的方式:

我的@l = ();说@l.elems == 0;说@l == ();说@l.Bool;

FAQ: In Raku how to check if a list is empty ? Are there more idiomatic ways than:

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

The doc on list recommends smartmatching

say $l ~~ ();

  1. Do you know other ways ?
  2. Can you explain why () === () is wrong even if "" === "" is right: I'm not clear on that.

解决方案

Of those suggested:

say @l.elems == 0;

This is a good one to avoid, because it forces evaluation of all elements in a lazy list (which may lead to an exception if there are iterators marked as lazy, since the alternative would be running until all memory is exhausted).

say @l == ();

This works, but has the same problem as above. The == operator is numeric equality, and so it will coerce both sides to a number and then compare them. That also boils down to @l.elems (via. @l.Numeric). You could write this form cheaper as @l == 0, which is the neatest way if you really do want to ask for how many elements there are in total.

say @l.Bool;

This is better, because in a lazy list it only forces evaluation of one element at most to answer the question. However, it's actually the inverse of what was asked: this is True if the array is not empty. It's more natural to use the ? and ! prefix operators like this:

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

Though often you don't even need to do that, because things like if and unless provide a boolean context. Thus one could write:

if @l { }        # not empty
unless @l { }    # empty

These are probably the best ways.

As to other suggestions:

say $l ~~ ();

This is fine, though probably slower than the boolification approach.

() === () is wrong even if "" === "" is right

That's because List is a reference type, not a value type. Since () constructs a distinct empty list each time, they are distinct objects, and so will compare as non-identical. You can use eqv instead:

say () eqv ()    # True

But don't use this to check if a list is empty, because it's probably overly specific. For example:

my @l; say @l eqv ();    # False
my @l; say @l eqv [];    # True

This is because () is of type List, while my @l declares an Array. In general, you don't want to care what type is really there.

Finally, about this line:

my @l = ();

The assignment of () is pointless; my @a already creates an empty Array. In fact, it's a common enough code smell that Comma IDE gives a weak warning about this:

这篇关于检查列表是否为空 (Raku)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆