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

Nor*_*her 5 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";
Run Code Online (Sandbox Code Playgroud)

产生输出:

aref = 1 2 3
a = 1 99 3
Run Code Online (Sandbox Code Playgroud)

输出显示@a并且@$aref不引用相同的数组.

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

我知道当你分配给一个数组时,赋值的右边是一个列表上下文,所以它@$aref被强制转换为它的元素列表.有没有办法给这个@a引用的数组命名$aref

Bor*_*din 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";
Run Code Online (Sandbox Code Playgroud)

产量

aref = 1 99 3
a    = 1 99 3
Run Code Online (Sandbox Code Playgroud)

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

这是一个使用的版本,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";
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用alias而不是alias_r使用

alias @$aref, my @a;
Run Code Online (Sandbox Code Playgroud)

  • 绝对避免使用这个答案中的第一个建议; 当你不需要时,没有充分的理由使用非词法变量. (3认同)
  • 包变量有词法范围?这是假的."我们的"所创造的词汇别名是词汇,但数据仍然是全球性的,具有所有可能带来的破坏.perl 5.18介绍(实验)词汇subs; 这是人们长久以来想要的东西. (2认同)

ike*_*ami 6

  1. our @array; local *array = $aref;
    
    Run Code Online (Sandbox Code Playgroud)

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

  2. use Data::Alias qw( alias );
    alias my @array = @$aref;
    
    Run Code Online (Sandbox Code Playgroud)

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

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

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