示例:
use strict;
my $file = shift;
open(IN, $file) || die "Unable to open $file\n";
open(OUT, ">$file.$$") or die $!;
my $file = shift
发生了什么?
答案 0 :(得分:28)
如果在主程序中使用,它将shift
(删除并返回)@ARGV
中的第一个值,即程序的参数列表。如果在子例程中使用,它将从@_
(子参数列表)中移出第一个值。有关详细信息,请参阅documentation。
答案 1 :(得分:13)
您可以阅读shift
上的文档。很清楚。 shift
接受一个数组并提取第一个元素(实际上将其从数组中删除)。如果您不提供任何数组,它将使用@ARGV
(程序命令行的参数)来读取数据。如果你在函数内,它使用@_
,即函数的参数。
示例:
my @array = (1, 2, 3);
my $value = shift @array;
print $value; # will print '1'
答案 2 :(得分:5)
shift
使用@_
变量,其中包含传递给函数的值,shift
使用@ARGV
传递给脚本本身的值shift
在函数之外引用。
一个小心的注意事项:这可能是明智的,特别是在许多路径包含空格的Windows中,当您将文件名和路径传递给脚本或函数时,将文件名和路径放在单引号中。这将告诉Perl您传递的是单个标量值而不是值数组。如果要插入部分名称,可以使用双引号。例如:
my $path = 'C:\Goat Kids';
func("$path\\goat.txt");
或者,如果要将文件名直接传递给脚本,请从命令行:
perl goat.pl "C:\Goat Kids\goat.txt"
答案 3 :(得分:2)
之前的答案描述了shift
的工作原理。我想评论为什么在你自己的程序中使用它是个好主意。
默认情况下,Perl是一种传递引用语言。如果子例程修改了其参数,则调用者将看到这些(有时是意外的)更改。使用shift
将子例程参数分配给私有变量是一种很好的做法。这样,如果对其进行任何更改,调用者将无法看到它。例如,下面的代码输出
1
2
2
第一个子例程修改其参数,调用者看到更改。第二个子例程修改其参数的私有副本,并且此更改在调用者中不可见。
use strict;
use warnings;
sub pass_by_ref {
$_[0] = 2;
}
sub pass_by_value {
my $x = shift @_;
$x = 3;
}
my $x = 1;
print $x, "\n";
pass_by_ref($x);
print $x, "\n";
pass_by_value($x);
print $x, "\n";