1

在 java 中,对于表示集合的类,如果它实现了可迭代接口,则可以在不了解集合的情况下使用 foreach 循环对集合进行迭代。

我们可以在 perl 中做类似的事情吗?假设我的 perl 类是一个集合。迭代集合的最佳方式是什么?

4

4 回答 4

2

如果您使用 Perl 哈希代替 Collection,那么您可以使用each它来迭代它。

每次调用都each %hash将返回下一个键/值对,或者最后返回一个空列表。

于 2013-02-25T16:26:58.243 回答
1

Perl 没有 Java 风格的迭代器,因为它不需要它们。Perl 内置了相当强大的散列和列表,它们取代了您将需要的大多数自定义集合,并且您已经可以轻松地循环它们。如果你想对每个元素做一些事情(特别是如果你想建立一个结果列表),map你可以将代码引用传递给类似的函数。

但是,如果您真的想要这种 Java 主义,您可以构建自己的迭代器类。它不必实现或扩展任何特定的接口,因为 Perl 鸭子类型——而且普通人无论如何也不使用迭代器,所以首先没有标准接口。并且和它没有任何关系foreach。:P

确实,最好只使用标准集合类型。我从来没有遇到过需要自定义集合的情况。

于 2013-02-25T16:10:15.523 回答
1

您可以使用闭包和函数式编程技术在 perl 中创建任意复杂的迭代器,因为当您需要超出 perl 内置的遍历数组和散列的能力时。这是说明该技术的简单示例 - 在这种情况下,它非常无用,因为对于这种特殊情况,迭代器是不必要的。但正如我所说,这种技术可以有效地应用于其他场景。此示例将向后遍历数组,跳过我们想要排除的元素(在本例中为字母“c”)。

sub gen_iter {
    my @collection = @_;
    return sub {
        while (my $item = pop @collection) {
            next if $item eq 'c';
            return $item;
        }
    }
}

my $it = gen_iter((qw/a b c d e f g/));

# prints 'gfedba'
while (my $item = $it->()) {
    print $item;
}

我建议阅读免费的电子书“High-Order Perl”并阅读有关迭代器的章节。它有一些很棒的有用的例子。

于 2013-02-26T18:58:05.633 回答
0

Perl 的两个内置集合——数组和散列——有多种迭代方式:

  1. foreach循环:循环(但不延迟迭代)给定列表中的每个项目。在哈希上使用 this 可能是错误的,您应该遍历valueskeys

    foreach my $key (keys %hash) {
      do something;
    }
    
  2. 迭代器:您可以使用该函数each遍历“集合” each。每次调用它时,它都会返回一个键/索引列表和一个值。如果没有其他项目,它将返回一个错误值:

    while (my ($key, $value) = each %hash) {
      do something;
    }
    

    每个数组/哈希只能有一个这样的迭代器。on 数组的这种用法each是一个相当新的功能。

  3. each可以通过闭包来扩展该习惯用法以创建自定义迭代器:

    my %hash = ...;
    my @keys = keys %hash; # cache the current keys
    my $i = 0;
    my $iter = sub {
      return unless $i < @keys;
      my $key = $keys[$i++];
      return ($key, $hash{$key});
    };
    ...;
    while (my ($key, $value) = $iter->()) {
      do something;
    }
    
于 2013-02-25T16:26:13.810 回答