ala*_*ska 5 perl weak-typing implicit-conversion
我是Perl的新手,请有人为我解释以下脚本:
#!/usr/bin/env perl
use strict;
use warnings;
sub f1($) { my ($v) = @_; print "f1 $v\n"; }
sub f2(@) { my ($v) = @_; print "f2 $v\n"; }
my $s = "ww";
my @a = ("xx", "yy", "zz");
f1 $s; f1 @a; f2 $s; f2 @a;
Run Code Online (Sandbox Code Playgroud)
我的电脑输出是:
f1 ww
f1 3
f2 ww
f2 xx # why!!
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释为什么第四个输出是xx?我认为它应该是zz,因为当数组转换为标量时,它应该是数组的最后一个元素.
不,有这样的声明:
my ($v, $foo, $bar) = @_;
Run Code Online (Sandbox Code Playgroud)
$v将被分配数组中的第一个值@_,$foo第二个值,依此类推。这是因为括号强加了列表上下文。任何多余的值都将被忽略,除非您的变量之一是数组,在这种情况下它将吸收所有剩余的值。
my ($v, @foo, $bar) = @_; # wrong! $bar will never get any value
Run Code Online (Sandbox Code Playgroud)
$v将获得第一个值,@foo其余所有值。$bar将是未定义的。
您可能正在考虑使用列表进行分配:
my $v = qw(a b c);
Run Code Online (Sandbox Code Playgroud)
但这是错误的,并且会导致错误:
Useless use of a constant (a) in void context at -e line 1.
Useless use of a constant (b) in void context at -e line 1.
Run Code Online (Sandbox Code Playgroud)
这是因为 LHS 使用标量上下文,它将(或多或少)类似于:
'a';
'b';
my $v = 'c';
Run Code Online (Sandbox Code Playgroud)
您可能会注意到,如果我们通过放入$v括号来强加列表上下文,我们会得到不同的结果:
my ($v) = qw(a b c); # $v is now 'a'
Run Code Online (Sandbox Code Playgroud)
预计到达时间:关于原型:
在 中f1,您看到数组被强制进入标量上下文,因为子例程需要一个标量参数。这就是为什么f1用数组打印3(大小)。当原型查找数组时,该数组保留在默认列表上下文中,并且按正常方式完成分配(如上所述)。
作为额外说明:原型有一个非常具体的用途,使子例程在参数处理方面更像某些内置函数。如sort { code here }或push @array, $foo。
如果这不是您想要的,您应该跳过原型并简单地编写:
sub f1 {
...
}
Run Code Online (Sandbox Code Playgroud)
文档在这里