typeglob别名

问题描述 投票:3回答:4

好的,所以创建对数组的引用很容易......

my @a;
my $b=\@a;
#can now reference the same list of scalars from either @$b or @a

但是我怎么能这样做呢?例如:

my $a=[1..4];
my @b;
#some magic happens here and now @b is an alias for @$a
@b=(6..10);
print "@$a\n";  #should print "6 7 8 9 10"

我认为这会通过typeglobs发生,但那些只是躲避我。想法?

对哈希和数组做同样的事情也会很好。

编辑:这似乎工作,但它有点kludgy因为它只是将anon数组元素复制到“别名”,然后重新指向数组:

my @b=@$a;
$a=\@b;

有更好的想法吗?

perl
4个回答
8
投票

三种方式:

  1. Refaliasing。 5.22添加了一个实验性功能,完全符合您的要求。 use experimental qw( refaliasing ); \my @B = $A; 5.26增加了第二个实验性功能,允许以下内容: use experimental qw( refaliasing declared_refs ); my \@B = $A; 请注意,作为实验性功能,这些功能随时可能会更改和删除。
  2. 全球别名 Perl调用“type glob”或简称“glob”,它的符号表条目数据结构。可以将此数据结构中的条目设置为对该引用的名称的引用。 local our @B; *B = $A; # Sets the array slot of "B", @B. 请注意,我们必须使用包变量,因此该变量是全局可见的。
  3. Data::Alias alias my @B = @$A;

5
投票

perl程序中的所有变量都存储在名称空间中。有两种类型的命名空间:

  1. 符号表。它是一个存储全局变量记录的全局哈希。
  2. 词汇范围。它是存储的匿名临时内存,而不是特定的符号表,但它附加到程序块。它们存储我们只能在该程序块中看到的变量。

Typeglobs用于定义符号表的记录(变量,数组等),但不用于定义词法范围。所以,当你使用这部分代码时:

my @b;
*b = $a;

你会得到的:

Name "main::b" used only once:

这告诉我们记录main :: b没有被我们在Symbol表中定义,但是我们可以使用修饰符“our”来完成它。因此,当你这样写:

our @b;
*b = $a;

我们可以为我们获得有用的结果,因为* b存储在符号表中,我们可以使用运算符* typeglob。


3
投票

我想我明白了......

my $a=[1..4];
our @b;
*b=$a;
print "@b\n";
@b=(6..10);
print "@$a\n";

打印:

1 2 3 4
6 7 8 9 10

“我们的”对我来说仍然有点神秘......我想我有一些阅读要做......


0
投票

$ a和@a不是一回事。 $ a,因为你第一次指定它是对匿名数组的引用。它与@a没有任何关系,@ a是一个数组(不是引用)。

$ b = \ @a#$ b包含对@a的引用,但不包含对$ a的引用。

$ a,@ a,%a都是不同的变量。所以,如果你有

我的@a =(1,2,3,4);

然后你宣布

我的$ a;

$ a不包含对@a的引用;

变量按类型保存在符号表中;标量,哈希,数组等。这样你就可以拥有$ a,@ a,%a,&a ......并且彼此之间不会发生冲突。

关键在于

#some magic happens here and now @b is an alias for @$a

没有发生。它仍然指向存储@a的内存区域,该区域与存储$ a的区别不同。

© www.soinside.com 2019 - 2024. All rights reserved.