有没有办法让一个类重载数组解引用器,这样我就可以将该类的一个实例提供给 foreach
并在每次迭代时运行一个自定义函数?
我试过:
@{}
并将其分配给子。但是,在这种情况下, sub 只执行一次,并且应该返回对要迭代的数组的引用。几乎但不完全是我想要的。 <>
。这将在每次读取尝试时执行分配的功能。正是我想要的,但是它适用于 while
循环,而不适用于 foreach
。 重载.pl
use overloaded;
$class = overloaded->new();
$class->add("Hi");
$class->add("Hello");
$class->add("Yeet");
foreach $string (@$class) {
print("NEXT ITEM: ".$string."\n");
}
while ($item = <$class>) {
print("NEXT ITEM: ".$item."\n");
}
重载.pm
package overloaded;
use strict;
use warnings;
use Data::Dumper;
use overload '@{}' => \&next, '<>' => \&fetchNext;
sub new {
my ($class, %args) = @_;
$args{fields} = ();
$args{pos} = 0;
return bless { %args }, $class;
}
sub add {
my ($self, $elem) = @_;
push(@{$self->{fields}}, $elem);
}
sub fetchNext {
my ($self) = @_;
print("reading next line...\n");
return $self->{fields}->[$self->{pos}++];
}
sub next {
my ($self) = @_;
print ("getting next array item\n");
return \@{$self->{fields}};
}
1;
输出:
$ perl overloading.pl
getting next array item
NEXT ITEM: Hi
NEXT ITEM: Hello
NEXT ITEM: Yeet
reading next line...
NEXT ITEM: Hi
reading next line...
NEXT ITEM: Hello
reading next line...
NEXT ITEM: Yeet
reading next line...
最佳答案
您在这里遇到的问题不是 @{...}
之间的区别和 <...>
但foreach
之间的区别和 while
.
一个 while
循环的行为有点像迭代器,因为它的执行看起来像这样:
while (you can run a piece of code and get back a value) {
do something
}
所以每次循环时,它都会执行
while
中的一段代码。条件并期望获得单个值。 while
中的代码条件在标量上下文中运行。一个
foreach
另一方面,循环只执行一次它的代码并期望得到一个值列表。循环开始处括号之间的代码在列表上下文中执行。这就是为什么您使用以下命令一次一行读取一个大文件的原因:
while (<$file_handle>) {
...
}
这一次只能从文件中读取一条记录。如果您使用的是
foreach
像这样循环:foreach (<$file_handle>) {
...
}
那么您将立即从文件句柄中取回所有记录 - 显然,这需要更多的内存。
取消引用数组引用也是如此。您可以同时获取所有值。被覆盖的方法 (
next()
) 只会被调用一次,并且预计会返回一个值列表。
关于Perl 重载 @{} 以便您可以为 foreach() 提供一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55903248/