3

我在 Perl 中做一些工作,但我使用条件运算符遇到了一个奇怪的结果。

有问题的代码:

($foo eq "blah") ? @x = @somearray : @y = ("another","array");

尝试编译此代码会导致错误“ Assignment to both a list and a scalar at XXX line YY, near ');'”。在试图查明错误的来源时,我使用几种不同的方式在 Perl 中表示数组,它们都返回相同的错误。现在起初我认为这只是赋值语句的一些愚蠢的明显错误,但为了满足我的好奇心,我以更详细的方式重写了语句:

if($foo eq "blah") {
    @x = @somearray;
} else {
    @y = ("another","array");
}

该版本的代码编译得非常好。

条件运算符的工作方式和我在这里遗漏的基本 if-else 语句的工作方式之间是否有一些细微的区别?我一直认为条件运算符只是第二条语句的简写版本。如果两者在功能上没有区别,为什么 Perl 会反对第一个语句,而不反对第二个?

4

5 回答 5

15
$ perl -MO=Deparse -e'($foo eq "blah") ? @x = @somearray : @y = ("另一个","数组");'
在 -e 第 1 行,靠近 ");" 处为列表和标量赋值
-e 有编译错误。
$foo eq '废话' ?(@x = @somearray) : @y = ('another', 'array');
$ perl -MO=Deparse -e'($foo eq "blah") ? @x = @somearray : (@y = ("another","array"));'
$foo eq '废话' ?(@x = @somearray) : (@y = ('another', 'array'));
-e 语法OK

注意括号:?:绑定比=.

于 2009-11-12T20:39:25.440 回答
9

Perl 条件运算符的意思是

$variable = (表达式) ? 真赋值:假赋值;

您正在做的事情看起来应该可以工作,并且与 if/else 语句基本相同。但这与规范的差异足以产生问题。

于 2009-11-12T20:49:07.553 回答
7

perlop文档明确指出您应该在赋值运算符周围加上括号

如果您不了解运算符优先级,则不使用括号是您自己的后盾。别再为了自己的利益而变得太聪明了!

于 2009-11-12T20:41:21.080 回答
6

这与您的问题有些正交,但需要指出:Perl 的条件运算符将上下文从第一个参数传播到第二个或第三个参数,因此这会给您带来不希望的结果:

$x = ($foo eq "blah") ? $somevalue : ("another","array");

如果条件为假,$x则改为分配一个整数值2(第三个参数中的元素数)。

另一方面,如果您尝试执行纯标量赋值:

# this is wrong, for the same order-of-operations reasons as with arrays
($foo eq "blah") ? $x = $somevalue : $x = "another value";

这将是解决这种情况的合理(也是最佳)方法:

$x = ($foo eq "blah") ? $somevalue : "another value";

同样,您可以通过以下方式优化原始代码:

@x = ($foo eq "blah") ? @somearray : ("another","array");
于 2009-11-12T20:58:07.800 回答
2

这将是使用较低优先级的“和”和“或”运算符的好地方。

$foo eq 'blah' and @x = @somearray or @y = ('another', 'array');

只要您确定 @x = @somearray 将始终为真。或者你可以翻转它们。

于 2009-11-12T20:55:18.557 回答