问题1:
我想将一个数组传递给一个函数.但是在函数中改变了传递的参数.是值吗?
问题2:
#my ($name,$num,@array)= @_; <=1 ) my $name = shift; <=2 ) my $num = shift; my @array = shift;
案例1和案例2有不同的输出.它为什么会发生?
#!/usr/bin/perl use strict; my @test1; push @test1,['a',1]; push @test1,['b',['c',['d',['e',1]; for (my $i=0; $i< scalar(@test1); $i++) { print "out1: $test1[$i][0] $test1[$i][1]\n"; } test_func("test_func",10,@test1); sub test_func { #my ($name,@array)= @_; <=1) my $name = shift; <=2) my $num = shift; my @array = shift; print "$name\n"; print "$num\n"; for (my $i=0; $i< scalar(@test1); $i++) { print "$array[$i][0] $array[$i][1]\n"; } for (my $i=0; $i< scalar(@test1); $i++) { if ($array[$i][0] eq 'a') { $array[$i][0] = 'z'; } } for (my $i=0; $i< scalar(@test1); $i++) { print "change: $array[$i][0] $array[$i][1]\n"; } } for (my $i=0; $i< scalar(@test1); $i++) { print "out2: $test1[$i][0] $test1[$i][1]\n"; }
#
以下是测试输出.
out1: a 1 out1: b 1 out1: c 1 out1: d 1 out1: e 1 test_func 10 a 1 b 1 c 1 d 1 e 1 change: z 1 change: b 1 change: c 1 change: d 1 change: e 1 out2: z 1 <= Why did it change? out2: b 1 out2: c 1 out2: d 1 out2: e 1
解决方法
I want to pass an array to a function […] has different output. Why did it occur?
您无法将数组传递给函数sub. Subs只能将标量列表作为参数.
test_func("test_func",@test1);
是相同的
test_func("test_func",$test1[0],$test1[1],$test1[2],$test1[3],$test1[4]);
当你这样做时,你正在test_func中创建一个新数组
my ($name,@array) = @_;
shift返回@_的第一个元素,它必然是一个标量. @_是一个数组,数组的元素是标量.相当于
my $name = shift(@_); my $num = shift(@_); my @array = splice(@_);
要将数组传递给子,通常会传递对它的引用.
test_func("test_func",\@test1); my ($name,$array) = @_; my $name = shift; my $num = shift; my $array = shift; say "@$array";
But the passed argument is changed in the function. Is it called by value?
Perl永远不会超值.它总是通过引用传递.如果更改@_的任何元素,它将更改调用者中的相应参数.
$perl -E'sub f { $_[0] = "def"; } my $x = "abc"; f($x); say $x;' def
但那不是问题.您不会更改@_的任何元素.你正在做的是改变$test [0]和$array [0]引用的单个数组.
这就是你在做什么:
my $ref1 = [ 'a',1 ]; # aka $test1[0] my $ref2 = $ref1; # aka $array[0] $ref2->[0] = 'z'; # Changes the single array (not $ref1 or $ref2).
它的缩写
my @anon = ( 'a',1 ); my $ref1 = \@anon; # aka $test1[0] my $ref2 = $ref1; # aka $array[0] $ref2->[0] = 'z'; # Changes @anon (not $ref1 or $ref2).
Storable的dclone可用于制作数组的“深层复制”.
my $ref1 = [ 'a',1 ]; my $ref2 = dclone($ref1); # clones the reference,the array,'a' and 1. $ref1->[0] = 'y'; # Changes the original array $ref2->[0] = 'z'; # Changes the new array