我可以在Perl中命名一个匿名数组吗?

时间:2015-07-29 16:02:45

标签: arrays perl

#!/usr/bin/perl -w

use strict;

my $aref = [1, 2, 3];
my @a = @$aref;              # this line
$a[1] = 99;
print "aref = @$aref\n";
print "a = @a\n";

产生输出:

aref = 1 2 3
a = 1 99 3

输出显示@a@$aref未引用相同的数组。

标记的行是我的问题所在。标量$aref的值是对匿名数组的引用。在标记的行中,我希望能够使数组变量@a引用该数组,但会发生的是复制匿名数组并且@a引用匿名数组的副本。赋值和打印语句显示了这一点。

我理解当你分配给一个数组时,赋值的右边是一个列表上下文,所以@$aref被强制转换为它的元素列表。有没有办法将名称@a赋予$aref引用的数组?

4 个答案:

答案 0 :(得分:7)

我想知道为什么你想要这样做?我认为这是一个性能问题,但通常的解决方案是通过引用传递您的数据。将$aref->[1]写为$a[1]

同样容易

您可以通过分配typeglob在包符号表中别名您的引用,但别名必须是包变量

use strict;
use warnings;

my $aref = [1, 2, 3];

our @a;
*a = $aref;

$a[1] = 99;

print "aref = @$aref\n";
print "a    = @a\n";

输出

aref = 1 99 3
a    = 1 99 3

有许多模块提供了很好的语法,并允许您为词法变量添加别名

这是一个使用Lexical::Alias的版本,它具有别名词汇变量的优点,并且可能比分配给typeglobs更强大。 Data::Alias的工作方式非常相似。输出与上面的

相同
use strict;
use warnings;

use Lexical::Alias qw/ alias_r /;

my $aref = [1, 2, 3];

alias_r $aref, \my @a;

$a[1] = 99;

print "aref = @$aref\n";
print "a    = @a\n";

另一种方法是使用alias代替alias_r

alias @$aref, my @a;

答案 1 :(得分:6)

  1. our @array; local *array = $aref;
    

    优点:5.6以来的内置功能。
    缺点:丑陋。使用全局变量,因此变量可以被称为subs。

  2. use Data::Alias qw( alias );
    alias my @array = @$aref;
    

    优点:清洁。
    缺点:几乎每个Perl版本都会破坏这个模块(尽管如果不是在实际发布之前就快速修复)。

  3. use feature qw( refaliasing );
    no warnings qw( experimental::refaliasing );
    \my @array = $aref;
    

    优点:内置功能。
    缺点:需要Perl 5.22+,即使这样,该功能也是实验性的。

答案 2 :(得分:1)

为了扩展Borodin的答案,我已使用Lexical::Alias模块对此进行了测试:

#!/usr/bin/perl -w

use strict;
use Lexical::Alias 'alias_a';

my $aref = [1, 2, 3];
my @a;
alias_a(@$aref, @a);
$a[1] = 99;
print "aref = @$aref\n";
print "a = @a\n";

答案 3 :(得分:1)

一种选择是使用CPAN中的Data::Alias包。

这样你可以写:

#!/usr/bin/perl

use Data::Alias qw( alias );

my $aref  = [1, 2, 3];

alias my @a = @$aref;

$a[1] = 99;
print "aref = @$aref\n";
print "a = @a\n";

关于SO的相关问题可以在这里找到:Assign address of one array to another in Perl possible?