在Perl中,赋值(以及操作数组和哈希)的结果取决于上下文。
my @arr = (10, 20, 30); my $count = @arr; # $count == 3 my ($first, $second) = @arr; # $first == 10, $second == 20
对于哈希:
my %h = (a=>1, b=>2, c=>3); my $size = %h; # 在现代版本的Perl中,$size == 3,但早期并非如此!
小心不要完全赋值数组的引用,而是复制内容!
数组引用赋值与数组内容复制有什么不同?
答案:
my @a = (1,2,3); my $ref = \@a; # $ref是数组的引用,通过$ref看到的更改会反映在@a上 my @b = @a; # @b是新数组,@b的更改不影响@a # 比较: push @$ref, 4; # @a现在是(1,2,3,4) push @b, 5; # @a保持(1,2,3,4); @b是(1,2,3,5)
故事1
在项目中,通过引用传递数组到子程序时,不理解这其实是引用:函数在调用处修改了它。出现了错误–在调用代码中的数据结构已经被“破坏”。期望的是复制,却得到了别名。
故事2
工程师以为标量赋值
%h会返回真实的对数。结果发现——在老版本的Perl中,这个行为是不同的:返回的是槽/桶的数量,而不是长度!最终有时返回的不是3,而是其他数字,这破坏了统计数据。
故事3
在一个大型ETL系统中,通过引用复制数组,然后意外地相互覆盖数据,因为所有人都在使用同一个数组,而不是独立的副本。诊断错误花费了几天时间。