在Perl中shift()有什么作用?


69

以下几行可能意味着什么?

my $x = shift;

1
Perl具有每个标准功能的内置文档。他们也在线。在这种情况下,“ perldoc -f shift”
Sherm Pendley's

36
他是否用Google都没关系。这是一个很大的问题,绝对应该成为Stack Overflow数据库的一部分。
cowgod

6
@friedo-同意100%!这不应成为“向我阅读文档”网站。
Sherm Pendley's

2
perldoc -f shift包含来自“ perlfunc”的有用信息。参见perfun甚至perlfun:shift()。没有一个答案能很好地完成文档的链接/拉取。因此,无论是否为“ RTFM”,都应包括参考。

Answers:


59

shift()是内置的Perl子例程,该例程将数组作为参数,然后返回并删除该数组中的第一项。通常的做法是通过shift调用获取传递到子例程中的所有参数。例如,假设您有一个foo接受三个参数的子程序。将这些参数分配给局部变量的一种方法是shift像这样:

sub foo() {
  my $x = shift;
  my $y = shift;
  my $z = shift;
  # do something
}

这里的困惑是,似乎shift并没有传递给数组作为参数。实际上,它是隐式传递给“默认”数组的,该数组@_位于子例程内部或子例程@ARGV外部。


或@ARGV,如果您不在某个函数中(请参阅我的回答)
Alnitak

1
您不希望在sub的名称后面加上'()-它应该是'sub foo {...'。使用'()',您是说foo不接受任何参数,在这种情况下,这不是您想要的
EvdB

3
我更喜欢用sub foo{ my($x,$y,$z) = @_ }自己,它不那么重复。
布拉德·吉尔伯特

14

shift函数从数组中删除第一个元素,然后返回它。该数组缩短了一个元素。

默认数组(如果未提供作为参数的数组)是@_在函数中,还是@ARGV在文件范围内。

因此,在这种情况下$x,要么被设置为第一个功能参数,要么被设置为第一个命令行参数。


7
应该添加的是@_是包含给函数提供的参数的数组,@ARGV是包含给程序提供的参数的数组。
斯万特

7

在Perl中,如果您未明确指定参数,则许多方法都使用默认变量($_@_)。您的代码与:

my $x = shift @_;

正如PullMonkey先前指出的那样,在子例程中@_包含传递给该子例程的参数(如中所述perlsub)。shift将从中删除第一个参数值@_并将其存储在中$x,因此$_[0]现在将为您提供第二个参数值传递给子例程参数。


3

这通常是一个成语:$ x是分配给传递给子例程的第一个参数的局部变量。

my ($x) = @_;

可能更清晰(并且不会修改参数列表)。


1

用外行的话来说,从一个非常高级的角度来看,shift占据了数组的第一个元素(最左边的部分),而pop则占据了数组的最后一个元素(最右边的部分)。

我的@ array1 =(5,6,7,8,9);
我的$ x = shift @ array1;
打印“ $ x \ n”;#5
打印“ @ array1 \ n”;#6 7 8 9

0

如果您在子例程中,则此行将shift打开@_(传入的参数)。
因此$x将是第一个项目popped@_数组。

所以通常你会看到 $x = shift if @_;


2
如果没有真正的需要。“我的$ x =班次;” 和“我的$ x; $ x =如果@_,则移位;” 是等效的,并且如果@_为空,都将导致$ x为undef,也不会违反strict或发出警告。唯一的区别是您必须输入的数量。
Dave Sherohman
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.