perl:“//”运算符?

时间:2011-09-13 22:08:13

标签: perl

我对使用“//”运算符有疑问,我的测试代码如下:

perl -e '@arr1=();@arr2=(1,2,3);@arr3=defined(@arr1)?@arr1:@arr2;print "[@arr3]\n"' 

[1 2 3] 

perl -e '@arr1=();@arr2=(1,2,3);@arr3=@arr1//@arr2;print "[@arr3]\n"' 

[0] 

perl -e '$v1=();$v2="123";$v3=defined($v1)?$v1:$v2;print "[$v3]\n"' 

[123] 

perl -e '$v1=();$v2="123";$v3=$v1//$v2;print "[$v3]\n"' 

[123]

我的问题是,为什么使用“//”运算符给出与在标量上使用“defined()?:”而不是数组(或哈希)相同的结果?

谢谢!

2 个答案:

答案 0 :(得分:20)

因为?:||&&的最左边的操作数 - 或者这个新的//的东西 - 总是在布尔值而不是列表上下文中进行评估,而其他操作数继承周围的环境。

@a = @b && @c;

装置

if (@b) {
     @a = @c;
} else {
     @a = scalar @b;
}

虽然

@a = @b || @c;

以及

@a = @b // @c;

都意味着

装置

if (@b) {
     @a = scalar @b;
} else {
     @a = @c;
}

将[{1}}分配给scalar时摆脱@b的唯一方法是使用@a

?:

当然这意味着

@a = @b ? @b : @c;

还有if (@b) { @a = @b; } else { @a = @c; } 可以是左值的属性:

?:

当然这意味着

(@a > @b ? @a : @b) = @c;

修改

if (@a > @b) { @a = @c; } else { @b = @c; } 的实施及其定义不同。错误提交。感谢。

答案 1 :(得分:10)

这与defined有关,而与//有关。来自perldoc -f defined

  

不推荐在聚合(哈希和数组)上使用defined它用于报告是否曾分配过该聚合的内存。在将来的Perl版本中,此行为可能会消失。

所以在你的第一个例子中,defined(@arr1)是假的;在第二个中,defined(@arr1)为真,@arr3包含scalar(@arr1)//中注明defined($a) ? $a : $b//之间的差异:

  

虽然它在C中没有直接的等价物,但Perl的or运算符与其C风格的||相关。实际上,它与$a // $b完全相同,只是它测试左手边的定义而不是真实。因此,defined($a) || $b类似于$a(除了它返回defined($a)的值而不是defined($a) ? $a : $b的值)并产生与$a // $b相同的结果(除了三元运算符形式可以用作左值,而$a不能)。这对于为变量提供默认值非常有用。如果您确实要测试是否定义了$bdefined($a // $b)中的至少一个,请使用(defined($a) ? $a : $b) = $c; # This is valid. ($a // $b) = $c; # This is not.

(强调我的。)

例如:

{{1}}