我有一些代码不能按照我期望的方式运行,而且我很感激帮助找出如何让它以我期望的方式运行。
我想使用子程序来修改输入数组。我想如果我传入对数组的引用,我对它做的任何更改都会反映在调用者的版本中。但它显然不起作用。
my @test_array = qw (zero one two three);
shift_array(\@test_array);
print "POST SUBROUTINE: $test_array[0]\n";
sub shift_array {
my @array = @{(shift)};
shift @array;
print "AFTER SHIFT IN SUB: $array[0]\n";
}
打印:
AFTER SHIFT IN SUB: one POST SUBROUTINE: zero
我希望它能同时打印one
。
所以我的问题是双重的:
1)为什么它不像我认为的那样表现?传递对数组的引用是否会创建数组的副本?
2)我如何得到我期望的行为?如何从调用者的输入数组副本前面滑出一个或多个元素的子程序?
提前感谢您提供的任何见解。
答案 0 :(得分:9)
因为my @array
是您为其指定了解除引用的原始数组的新数组。这是一份副本。
而是这样做:
sub shift_array {
my $array = shift;
shift( @$array );
}
编辑:我最初说解除引用它会产生问题,但使用@$array
仍然会取消引用它。正如@mob指出的那样,分配变量是创建新数组而不是更新现有引用的原因。
答案 1 :(得分:1)
这是Perl原型很有用的(极少数)案例之一。
#!/usr/bin/perl
use strict;
use warnings;
# Prototype forces the first argument to be a reference to an array
sub shift_array (\@) {
my $array = shift;
shift(@$array);
print "AFTER SHIFT IN SUB: @$array[0]\n";
}
my @test_array = qw (zero one two three);
shift_array(@test_array);
print "POST SUBROUTINE: $test_array[0]\n";
答案 2 :(得分:1)
我更喜欢在使用数组引用时更加一致,以最大限度地减少歧义:
#!/usr/bin/perl
use strict;
use warnings;
my @test_array = qw (zero one two three);
shift_array(\@test_array);
print "POST SUBROUTINE: $test_array[0]\n";
sub shift_array {
my $ref = shift;
shift @$ref;
print "AFTER SHIFT IN SUB: ${$ref}[0]\n";
}