perl:assign array=smth,它将返回false

perl:assign array=smth,它将返回false,perl,Perl,我有以下声明: my $iii=0; while (my @row = sub_undef()) { print $iii++."\n"; } sub sub_undef { if ($error) { return "something that will end the while loop"; } else { return 1; } } 在sub_unde()中,当我需要返回将在循环时结束的内容时,可能会出现一个case(错误)。 有什么办法吗 -- D

我有以下声明:

my $iii=0;
while (my @row = sub_undef()) { print $iii++."\n"; }

sub sub_undef {

  if ($error) {
    return "something that will end the while loop";
  } else {
    return 1;
  }
}
在sub_unde()中,当我需要返回将在循环时结束的内容时,可能会出现一个case(错误)。 有什么办法吗

--
Dmitry有两种方法:

解决方案1:如果不需要返回行,只需返回一个假标量:

sub sub_undef {
    # xxx
    return $error; # Already a true/false scalar
}
while (sub_undef()) { do_stuff(); }

解决方案2:返回arrayref而不是数组,如果出现错误,返回false(未定义)

sub sub_undef {
    # xxx
    return $error ? undef : $rowArrayRef;
}
while (my $row = sub_undef()) { do_stuff(@$row); }

解决方案3:返回元组($status,$rowArrayRef)


解决方案4:只有当行不能为空时才有效,除非根据您的业务案例发生错误

sub sub_undef {
    # xxx
    return $error ? () : @row;
}
while (my @row = sub_undef()) { do_stuff(@row); }

解决方案5:使用异常进行错误处理(
Try::Tiny


有两种方法:

解决方案1:如果不需要返回行,只需返回一个假标量:

sub sub_undef {
    # xxx
    return $error; # Already a true/false scalar
}
while (sub_undef()) { do_stuff(); }

解决方案2:返回arrayref而不是数组,如果出现错误,返回false(未定义)

sub sub_undef {
    # xxx
    return $error ? undef : $rowArrayRef;
}
while (my $row = sub_undef()) { do_stuff(@$row); }

解决方案3:返回元组($status,$rowArrayRef)


解决方案4:只有当行不能为空时才有效,除非根据您的业务案例发生错误

sub sub_undef {
    # xxx
    return $error ? () : @row;
}
while (my @row = sub_undef()) { do_stuff(@row); }

解决方案5:使用异常进行错误处理(
Try::Tiny

布尔上下文中的空数组为false1:

return () if $error;
方便的是,如果您不指定参数,这就是默认设置,因此您甚至可以只编写:

return if $error;

1) 这里的一个微妙之处是,在标量上下文中,空数组的计算结果为0(即其长度),而空列表的计算结果为
unde

@a = (); $b = @a;  # now $b is 0
$b = ();           # now $b is undef
但是,由于0和
undef
在布尔上下文中都为false,因此这里的差异实际上并不重要。有关更多详细信息,请参阅


编辑:如果您需要区分错误情况和数据不足,最好使用for errors并返回一个空列表作为数据结尾。然后,您的循环将如下所示:

eval {
    while (my @row = sub_undef()) { 
        # do something with @row
    }
};
if ($@) {
    # oops, we got an error, handle it
}
或者,使用:

布尔上下文中的空数组为false1:

return () if $error;
方便的是,如果您不指定参数,这就是默认设置,因此您甚至可以只编写:

return if $error;

1) 这里的一个微妙之处是,在标量上下文中,空数组的计算结果为0(即其长度),而空列表的计算结果为
unde

@a = (); $b = @a;  # now $b is 0
$b = ();           # now $b is undef
但是,由于0和
undef
在布尔上下文中都为false,因此这里的差异实际上并不重要。有关更多详细信息,请参阅


编辑:如果您需要区分错误情况和数据不足,最好使用for errors并返回一个空列表作为数据结尾。然后,您的循环将如下所示:

eval {
    while (my @row = sub_undef()) { 
        # do something with @row
    }
};
if ($@) {
    # oops, we got an error, handle it
}
或者,使用:


空列表的赋值将计算为false

  if ($error) {
    return ();
  } else {
    return 1;
  }

空列表的赋值将计算为false

  if ($error) {
    return ();
  } else {
    return 1;
  }

return 1
似乎表明您确实想返回标量。如果您按照以下方式编写循环

while (my ($value) = iter()) {
   ...
}
然后你可以发出三种状态的信号:

  • 返回$value用于成功返回。由于
    my($value)
    中的参数,您甚至可以安全地返回false或未定义的内容,而不会导致循环退出

  • 返回。这将导致循环结束后继续执行

  • die“message”
    发出错误信号。这将导致程序结束,除非使用
    eval BLOCK
    捕获异常


返回1
似乎表明您确实想返回标量。如果您按照以下方式编写循环

while (my ($value) = iter()) {
   ...
}
然后你可以发出三种状态的信号:

  • 返回$value用于成功返回。由于
    my($value)
    中的参数,您甚至可以安全地返回false或未定义的内容,而不会导致循环退出

  • 返回。这将导致循环结束后继续执行

  • die“message”
    发出错误信号。这将导致程序结束,除非使用
    eval BLOCK
    捕获异常


您这样问是因为通常返回数组吗?您这样问是因为通常返回数组吗?我无法编译解决方案3;
while
-条件似乎不能包含多个语句;-)for循环可能工作得更好:
for(my($error,$row)=sub_unde();!$error;($error,$row)=sub_unde()){…}
@amon-ups,你是对的。我试图不必要地保存代码行,这是我的第一个反射,但是词法变量的范围从下一个语句开始。你的
$错误
指的是全局错误。(来自Golang的“逗号,ok”习惯用法是错误管理的一个很好的方法,但它不能很好地映射到Perl);
while
-条件似乎不能包含多个语句;-)for循环可能工作得更好:
for(my($error,$row)=sub_unde();!$error;($error,$row)=sub_unde()){…}
@amon-ups,你是对的。我试图不必要地保存代码行,这是我的第一个反射,但是词法变量的范围从下一个语句开始。你的
$错误
指的是全局错误。(Golang中的“逗号,ok”是错误管理的一个很好的用法,但它不能很好地映射到Perl。)我感到困惑。我会使用empty
return
来表示“没有更多的事情要做”,而如果终止是由于错误造成的,那么引发异常对我来说似乎更好。毕竟,除了设置一个全局值或其他什么,还有什么方法可以找出空
返回值
错误的原因吗?@Sinan:我把OP的问题理解为只是想找到一种方法“在循环时返回将结束的内容”。如果OP需要区分错误和数据结束条件,你是对的,这会更有意义