写下以下内容的正确方法是什么:
while ( my $first = $iterator->next && my $second = $iterator->next ) {
# do work
}
这不会运行 - 我希望$first
和$second
在while
循环内的适当范围内。
答案 0 :(得分:17)
你想在赋值表达式周围使用括号。
while ((my $first = $iterator->next) && (my $second = $iterator->next)) {
# ...
}
&&
的优先级高于=
,因此您的原始代码似乎正在尝试执行x && y = z
之类的作业。
答案 1 :(得分:11)
这是and
比&&
更合适的地方:
#!/usr/bin/perl
use strict; use warnings;
my $it = make_iterator();
while ( my $first = $it->() and my $second = $it->() ) {
print "$first\t$second\n";
}
sub make_iterator {
my @x = qw(a b c);
return sub {
return shift(@x) if @x;
return;
};
}
输出:
C:\Temp> it a b
我很想将$second
中的赋值从while
中取出(取决于迭代器的意义而不是返回偶数个元素):
while ( my $first = $it->() ) {
defined(my $second = $it->())
or warn "Iterator returned odd number of elements\n"
and last;
print "$first\t$second\n";
}
输出:
C:\Temp> it a b Iterator returned odd number of elements
答案 2 :(得分:8)
我倾向于写这样的东西:
while( my( $first, $second ) = map { ... } 1..2 ) {
...
}
您可能不喜欢这种语法,因为您不习惯这样做,但它遵循一些我认为使代码更容易的规则:
然而,还有另一个问题。你必须弄清楚你在while
条件下测试的是什么,并向下一个程序员明确说明。我不确定为什么你在那种情况下有两件事。如果只有一件东西(即未经处理的奇怪人会发生什么事情),可以读取迭代器吗?
更好的解决方案是在不显示机制的情况下显示您尝试做的事情。我不知道你的迭代器有什么,我可能会建议你用另一个返回两个项目的方法来装饰它(如果它在最后,可能是空列表):
while( my( $first, $second ) = $iterator->read_two ) {
...;
}
如果情况不明确,请用一种方法来装饰它以询问特定问题:
while( $iterator->two_things_left ) {
my( $first, $second ) = $iterator->read_two;
...;
}
答案 3 :(得分:1)
尝试:
my $first;
my $second;
while (($first = $iterator->next) && ($second = $iterator->next)) {
# do work
}