我对使用“//”运算符有疑问,我的测试代码如下:
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()?:”而不是数组(或哈希)相同的结果?
谢谢!
答案 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
不能)。这对于为变量提供默认值非常有用。如果您确实要测试是否定义了$b
和defined($a // $b)
中的至少一个,请使用(defined($a) ? $a : $b) = $c; # This is valid. ($a // $b) = $c; # This is not.
。
(强调我的。)
例如:
{{1}}