三元运算符不允许迭代运算符,但if-else呢?

时间:2016-10-05 19:42:05

标签: perl foreach ternary-operator

我注意到,如果我用一个三元运算符替换我正在使用的if-else语句,那么当我尝试运行代码时,我会收到编译错误。我相信罪魁祸首是我foreach()内的if-else循环。你知道为什么三元运算符的行为与此实例中的if-else结构的行为不一样吗?

我的代码看起来像这样

#!/program/perl_v5.6.1/bin/perl5.6.1

use strict;
use warnings;


my $fruits_array_ref = &get_fruits();
if($fruits_array_ref != 0) {
    print("$_ is a fruit.\n") foreach(@$fruits_array_ref);
}
else {
    print("Maybe you like vegetables?\n");
}


sub get_fruits() {
    my @fruit_list;
    my $shopping_list = "/home/lr625/grocery_items";

    open(my $shopping_list_h, "<", $shopping_list) or die("Couldn't open.\n");
    while(my $line = <$shopping_list_h>) {
        next if $line =~ /^\#/;
        chomp($line);
        push(@fruit_list, $line);
    }
    close($shopping_list_h) or die("Couldn't close.\n");

    scalar(@fruit_list) > 0 ? return(\@fruit_list) : return(0);
}

我在购物清单中的数据看起来像

# this is a header
# to my grocery list
apple
banana
grape
orange

我正在用if-else运算符替换?:,现在在main函数中看起来像这样。

my $fruits_array_ref = &get_fruits();
$fruits_array_ref != 0 ? print("$_ is a fruit.\n") foreach(@$fruits_array_ref) : print("Maybe you like vegetables?\n");

另外,作为参考我的错误说。

  

test.pl第8行的语法错误,靠近“)foreach”

     

由于编译错误,test.pl的执行中止。

4 个答案:

答案 0 :(得分:8)

if-else是一个流控制结构,?-:是一个将表达式作为操作数的运算符。 foreach是流控制结构,而不是表达式。

您可以使用do

将任何代码块转换为表达式
$fruits_array_ref != 0
    ? do { print "$_ is a fruit.\n" for @$fruits_array_ref }
    : print "Maybe you like vegetables?\n";

但为什么?

答案 1 :(得分:4)

其他答案已经指出,您不能按照您尝试的方式使用三元运算符。为了完整起见并为您提供一些合理的用例,请查看以下示例:

#1:用作子程序参数

testSub($var eq 'test' ? 'foo' : 'bar');

如果testSub等于字符串foo,您可以在此处查看如何使用参数$var调用子例程test。否则,将testSub调用bar。这很有用,因为您不能将if-else结构用作子参数。

#2:用于条件分配

my $result = $var eq 'test' ? 'foo' : 'bar'; # $result will contain 'foo' or 'bar'

三元运算符并不是if-else结构的简单替代。由于它返回一个值(此处为foobar),因此使用此值也是有意义的。如果您不打算使用返回的值,则应该使用通常的if-else

答案 2 :(得分:1)

三元运算符在?:之前获取参数,请参阅in perlop。它可以评估表达式并将其结果用于此。但循环不是一种表达,不能“运行”。内。

对于演示 - 如果你坚持,你可以调用一个作为副作用打印的功能

sub greet { say "hello" for 1..3 }

my $x = 1;
($x == 1) ? greet() : say "bye";

Actualy在生产代码中执行此操作是另一回事,可能是一个坏主意。重点是完全依赖副作用,与我们通常想做的相反。

要解释我上面的评论 - 三元运算符的要点是返回一个值,在一个语句中可以选择两个值。虽然它是等同的&#34;对于if-else,它的使用(理想情况下)意味着非常不同。因此,以任何方式在?:参数内进行一些其他处理实际上是滥用符号,副作用,因为它们旨在产生要返回的值。打印出来与生成和返回值的想法相反。这不是批评,操作符​​经常被许多人用作语法快捷方式。

从这个意义上讲,我建议你回复一个if-else来做所显示的事情。

答案 3 :(得分:1)

$ cat output.txt 1 Hello 2 World 语句修饰符只能在语句的末尾使用。

您为什么使用foreach?如果您想要一个结果,通常只会这样做。

您可以将?:打包在print...foreach...中,也可以使用do {...}代替map。或者只是将它留作if / else。