从概念上讲,正常的赋值总是对数据进行浅拷贝。
通过“浅”,我的意思是 whenmy $foo = \@array
是对一个数组的引用,然后对同一个数组my $bar = $foo
进行$bar
不同的引用,所以当你时push @$bar, $quux
,你会像你时一样附加到同一个数组push @$foo, $quux
,但是如果你这样做$bar = \@another_array
,那么$foo
仍然指向原始数组。
“从概念上讲”,我的意思是你可以这样想。作为一种优化,Perl 偶尔会将这两个变量保存在内存的同一部分,直到您尝试修改一个。这称为“写时复制”。但是,除非您比大多数 XS 代码深入挖掘,否则您永远不应该注意到它的发生。
但是,在某些情况下,您可以有多个变量引用相同的数据。这些通常被称为“别名”。在foreach
,grep
和map
块中,$_
变量(或 的情况下的另一个词法变量foreach
)是当前正在处理的项目的别名:
foreach my $foo ($bar, $baz) {
# In here, $foo is an alias for $bar, then $baz.
# When $foo is aliased to $bar, then modifiying $foo
# also modifies $bar, and vice versa.
}
也可以通过分配给 glob 来创建别名。这是一个例子:
our $foo;
my $bar = 19;
*foo = \$bar; # alias $foo to $bar
$foo++;
$bar++;
print $foo + $bar; # 42
注意$foo
有一个包变量(our
);glob 赋值仅适用于包变量。但是 Data::Alias 和 Devel::LexAlias 允许你用词法变量 ( my
) 做类似的事情。
出现别名的另一种情况是@_
subs 中的数组。这里:
sub quux {
# In here, $_[0] is an alias for $foo
# In here, $_[1] is an alias for $bar
}
quux($foo, $bar);
最后,别名也可以通过谨慎使用绑定变量来伪造。