perl:"//"运算符?

ss-*_*erl 23 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]
Run Code Online (Sandbox Code Playgroud)

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

谢谢!!!

tch*_*ist 20

因为最左边的操作数?:,||或者&&-或者这newfanglulated //的thingie -布尔始终评估未列出的上下文,而其他操作数继承周围的环境.

@a = @b && @c;
Run Code Online (Sandbox Code Playgroud)

手段

if (@b) {
     @a = @c;
} else {
     @a = scalar @b;
}
Run Code Online (Sandbox Code Playgroud)

@a = @b || @c;
Run Code Online (Sandbox Code Playgroud)

并且

@a = @b // @c;
Run Code Online (Sandbox Code Playgroud)

两者都意味着

手段

if (@b) {
     @a = scalar @b;
} else {
     @a = @c;
}
Run Code Online (Sandbox Code Playgroud)

只有这样,才能摆脱scalar在分配@b@a是使用?:

@a = @b ? @b : @c;
Run Code Online (Sandbox Code Playgroud)

这当然意味着什么

if (@b) {
    @a = @b;
} else {
    @a = @c;
}
Run Code Online (Sandbox Code Playgroud)

还有一个属性?:可以是左值:

(@a > @b ? @a : @b) = @c;
Run Code Online (Sandbox Code Playgroud)

这当然意味着什么

if (@a > @b) {
    @a = @c;
} else {
    @b = @c;
}
Run Code Online (Sandbox Code Playgroud)

编辑

实施@a // @b 及其定义不同.错误提交.谢谢.

  • @ss-perl:我现在已经确定你发现了`//`运算符的定义和实现方式的合法错误. (2认同)

Jon*_*rdy 10

defined与其相关更多//.来自perldoc -f defined:

defined不推荐使用on aggregate(散列和数组).它曾用于报告是否已分配该聚合的内存.在将来的Perl版本中,此行为可能会消失.

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

虽然它在C语言中没有直接的等价物,但Perl的//运算符与它的C风格有关or.事实上,||除了它测试左手边的定义而不是真实之外,它完全相同.因此,$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.
Run Code Online (Sandbox Code Playgroud)