为何Perl中if语句内赋值与提前赋值的执行结果不同?
为什么Perl中if内赋值和提前赋值的判断结果不同?
差异原因
两个示例的核心区别在于赋值表达式的上下文返回值以及if条件判断的对象:
第一个示例:
if (($x) = @y)
Perl的if条件属于标量上下文,因此整个赋值表达式($x) = @y会返回列表@y的元素个数(此处是2)。由于2是非零值,在Perl中被视为真,因此进入yes分支;同时列表赋值操作会把@y的第一个元素0赋值给$x,最终输出yes 0。第二个示例:
my ($x) = @y; if ($x)
这里my ($x) = @y是列表赋值,$x得到@y的第一个元素0;后续if判断的是$x本身的值,而0在Perl中属于假值,因此进入no分支,最终输出no 0。
能否在if语句内同时完成赋值并检查值?
完全可以,只需明确控制上下文和逻辑优先级,常见两种写法:
写法一:先完成列表赋值,再检查变量值(注意括号控制优先级,因为
&&优先级高于=):$ perl -E 'my @y = (0, 1); my $x; if ((($x) = @y) && $x) {say qq[yes ], $x} else {say q[no ], $x}'此代码会先完成赋值,再判断
$x的值,最终输出no 0,和提前赋值的结果一致。写法二:直接取列表首元素赋值并检查(更直观):
$ perl -E 'my @y = (0, 1); if (my $x = $y[0]) {say qq[yes ], $x} else {say q[no ], $x}'这种方式直接将
@y的第一个元素赋值给$x,再判断其值,结果同样为no 0。
如果你的需求是“列表非空(赋值成功)且变量值为真”,写法一适用;若只需检查赋值后的变量值,写法二更简洁。
内容的提问来源于stack exchange,提问作者Kwabena
相关产品推荐
相关产品推荐

