typeglob别名

时间:2012-12-28 13:34:25

标签: perl

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

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;

有更好的想法吗?

4 个答案:

答案 0 :(得分: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;
    

答案 1 :(得分:5)

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

  1. 符号表。它是一个存储全局记录的全局哈希 变量
  2. 词汇范围。它是匿名的临时内存 存储,而不是一个特殊的符号表,但它附加到一个 你的程序块。它们存储我们只能看到的变量 在那个程序块中。
  3. Typeglobs用于定义Symbol表的记录(变量,数组等),但不用于Lexical 范围。所以,当你使用这部分代码时:

    my @b;
    *b = $a;
    

    你会得到它:

    Name "main::b" used only once:
    

    这告诉我们记录main :: b未在我们的符号表中定义,但我们可以使用修饰符“我们的”来完成。因此当你这样写:

    our @b;
    *b = $a;
    

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

答案 2 :(得分: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

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

答案 3 :(得分:0)

$ a和@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的地方不同。