Perl 三元条件运算符中的赋值问题

Posted

技术标签:

【中文标题】Perl 三元条件运算符中的赋值问题【英文标题】:Assignment inside Perl ternary conditional operator problems 【发布时间】:2010-09-05 18:12:34 【问题描述】:

我的程序中 Perl 代码的 sn-p 给出了错误的结果。

$condition ? $a = 2 : $a = 3 ;
print $a;

不管$condition的值是多少,输出总是3,怎么会?

【问题讨论】:

【参考方案1】:

这在 Perl documentation 中有解释。

由于 Perl 运算符优先级,语句被解析为

($condition ? $a= 2 : $a ) = 3 ;

因为 ?: 运算符产生一个可赋值的结果,所以将 3 赋值给条件的结果。

当 $condition 为真时,这意味着 ($a=2)=3 给出 $a=3

当 $condition 为 false 时,这意味着 ($a)=3 给出 $a=3

正确的写法是

$a = ( $condition ? 2 : 3 );
print $a;

我们在工作中被这个咬了,所以我在这里发帖希望其他人会发现它有用。

【讨论】:

"当 $condition 为真时,这意味着 $a=2=3 给出 $a=3" 我原以为 $a=2=3 会是表达式语法错误或需要左值错误等... 究竟是如何评估的? 你说得对,我会修改为 ($a=2)=3 而不是 $a=2=3【参考方案2】:

一旦你意识到你可能会遇到优先级问题,一个技巧来弄清楚 Perl 认为你的意思是什么:

perl -MO=Deparse,-p -e '$condition ? $a= 2 : $a= 3 ; print $a;'

在你的情况下,这会告诉你:

(($condition ? ($a = 2) : $a) = 3);
print($a);
-e syntax OK

...此时你应该说“哦,这就解释了”!

【讨论】:

Deparse 是一个非常巧妙的派对技巧。当然,一旦你怀疑一个优先级问题,你通常是解决问题的大部分方法;-)【参考方案3】:

只是为了扩展先前的答案...如果由于某种原因,作业需要成为条件的一部分,您会想这样写:

$condition ? ($a=2) : ($a=3);

如果您要根据条件分配给不同的变量,这将很有用。

$condition ? ($a=2) : ($b=3);

如果您选择变量,但无论如何分配相同的东西,您甚至可以这样做:

($condition ? $a : $b) = 3;

【讨论】:

【参考方案4】:

由于 Perl 运算符优先级,该语句被解析为:

($condition ? $a = 2 : $a ) = 3 ;

因为 ?: 运算符产生一个可赋值的结果,所以将 3 赋值给条件的结果。

当 $condition 为真时,这意味着 $a=2=3 给出 $a=3

当 $condition 为 false 时,这意味着 $a=3 给出 $a=3

正确的写法是

$a = $condition ? 2 : 3;

一般来说,您应该真正改掉使用条件语句进行赋值的习惯,就像在原始示例中一样——正是这种情况导致 Perl 以只写而闻名。

一个好的经验法则是,条件仅适用于简单值,绝不适用于有副作用的表达式。当您或其他人需要在八个月后阅读此代码时,您是否愿意这样阅读?

$x < 3 ? foo($x) : bar($y);

还是这样?

if ($x < 3) 
  $foo($x);
 else 
  $bar($y);

【讨论】:

【参考方案5】:

对以上 Tithonium 回答的一个建议:

如果您想为同一个变量分配不同的值,这可能会更好(抄本方式):

$a = ($条件) ? 2 : 3;

【讨论】:

以上是关于Perl 三元条件运算符中的赋值问题的主要内容,如果未能解决你的问题,请参考以下文章

C中的三元(条件)运算符

三元条件和赋值运算符优先级

赋值运算符左侧的三元条件运算符

为啥要使用三元运算符而不为“真”条件赋值 (x = x ?: 1)

三元运算符

Python算术运算符赋值运算符关系运算符逻辑运算符条件运算符(三元运算符)