三元运算符不允许在其中使用迭代运算符,但 if-else 允许吗?
Ternary operator doesn't allow iterative operator in it, but if-else does?
我注意到,如果我用三元运算符替换我正在使用的 if-else
语句,当我尝试 运行 我的代码时,我最终会遇到编译错误。我相信罪魁祸首是我 if-else
中的 foreach()
循环。您知道为什么三元运算符在这种情况下的行为与 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
替换为 ?:
运算符,现在在主函数中看起来像这样。
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");
此外,作为参考,我的错误是这样说的。
syntax error at test.pl line 8, near ") foreach"
Execution of test.pl aborted due to compilation errors.
if-else
是一个流控结构,?-:
是一个以表达式为操作数的运算符。 foreach
是流控结构,不是表达式。
您可以使用 do:
将任何代码块转换为表达式
$fruits_array_ref != 0
? do { print "$_ is a fruit.\n" for @$fruits_array_ref }
: print "Maybe you like vegetables?\n";
但是为什么呢?
三元运算符在 ?
和 :
之前采用 个参数 ,请参阅 in perlop。它可以计算一个表达式并为此使用它的结果。但是循环不是表达式,不能在里面 'run' 。
为了演示——如果你坚持的话,你可以调用一个函数作为副作用打印
sub greet { say "hello" for 1..3 }
my $x = 1;
($x == 1) ? greet() : say "bye";
实际上在生产代码中执行此操作是另一回事,可能不是一个好主意。重点是完全依赖副作用,这与我们通常想要做的相反。
为了解释我上面的评论——三元运算符的要点是 return 一个值,在一个语句中可以在两个值之间进行选择。虽然它是 if-else 的 "equivalent",但它的使用(理想情况下)意味着非常不同。因此,在 ?:
参数中进行一些其他处理,无论如何,实际上是对符号的滥用,是一种副作用,因为它们旨在产生一个要被 returned 的值。打印出它与产生和 returning 值的想法相反。这不是批评,运算符经常被许多人用作语法快捷方式。
从这个意义上说,我建议恢复到 if-else 来执行所示操作。
foreach
语句修饰符只能用在语句的末尾。
为什么要使用 ?:
?如果你想要一个结果,你通常只会这样做。
您可以将 print...foreach...
包裹在 do {...}
中,或者您可以使用 map
而不是 foreach
。或者将其保留为 if/else.
其他答案已经指出您不能按照您尝试的方式使用三元运算符。为了完整起见并为您提供一些合理的用例,请查看以下示例:
#1:用作子程序参数
testSub($var eq 'test' ? 'foo' : 'bar');
在这里您可以看到如果 $var
等于字符串 test
,如何使用参数 foo
调用子例程 testSub
。否则 testSub
将与 bar
一起调用。这很有用,因为您不能使用 if-else
结构作为子参数。
#2:用于条件赋值
my $result = $var eq 'test' ? 'foo' : 'bar'; # $result will contain 'foo' or 'bar'
三元运算符并不是 if-else
结构的简单替代。因为它 returns 一个值(这里是 foo
或 bar
)所以 使用 这个值也是有意义的。如果您不打算使用返回值,则应该使用通常的 if-else
。
我注意到,如果我用三元运算符替换我正在使用的 if-else
语句,当我尝试 运行 我的代码时,我最终会遇到编译错误。我相信罪魁祸首是我 if-else
中的 foreach()
循环。您知道为什么三元运算符在这种情况下的行为与 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
替换为 ?:
运算符,现在在主函数中看起来像这样。
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");
此外,作为参考,我的错误是这样说的。
syntax error at test.pl line 8, near ") foreach"
Execution of test.pl aborted due to compilation errors.
if-else
是一个流控结构,?-:
是一个以表达式为操作数的运算符。 foreach
是流控结构,不是表达式。
您可以使用 do:
将任何代码块转换为表达式$fruits_array_ref != 0
? do { print "$_ is a fruit.\n" for @$fruits_array_ref }
: print "Maybe you like vegetables?\n";
但是为什么呢?
三元运算符在 ?
和 :
之前采用 个参数 ,请参阅 in perlop。它可以计算一个表达式并为此使用它的结果。但是循环不是表达式,不能在里面 'run' 。
为了演示——如果你坚持的话,你可以调用一个函数作为副作用打印
sub greet { say "hello" for 1..3 }
my $x = 1;
($x == 1) ? greet() : say "bye";
实际上在生产代码中执行此操作是另一回事,可能不是一个好主意。重点是完全依赖副作用,这与我们通常想要做的相反。
为了解释我上面的评论——三元运算符的要点是 return 一个值,在一个语句中可以在两个值之间进行选择。虽然它是 if-else 的 "equivalent",但它的使用(理想情况下)意味着非常不同。因此,在 ?:
参数中进行一些其他处理,无论如何,实际上是对符号的滥用,是一种副作用,因为它们旨在产生一个要被 returned 的值。打印出它与产生和 returning 值的想法相反。这不是批评,运算符经常被许多人用作语法快捷方式。
从这个意义上说,我建议恢复到 if-else 来执行所示操作。
foreach
语句修饰符只能用在语句的末尾。
为什么要使用 ?:
?如果你想要一个结果,你通常只会这样做。
您可以将 print...foreach...
包裹在 do {...}
中,或者您可以使用 map
而不是 foreach
。或者将其保留为 if/else.
其他答案已经指出您不能按照您尝试的方式使用三元运算符。为了完整起见并为您提供一些合理的用例,请查看以下示例:
#1:用作子程序参数
testSub($var eq 'test' ? 'foo' : 'bar');
在这里您可以看到如果 $var
等于字符串 test
,如何使用参数 foo
调用子例程 testSub
。否则 testSub
将与 bar
一起调用。这很有用,因为您不能使用 if-else
结构作为子参数。
#2:用于条件赋值
my $result = $var eq 'test' ? 'foo' : 'bar'; # $result will contain 'foo' or 'bar'
三元运算符并不是 if-else
结构的简单替代。因为它 returns 一个值(这里是 foo
或 bar
)所以 使用 这个值也是有意义的。如果您不打算使用返回值,则应该使用通常的 if-else
。