Perl 为什么这个参考文件的定义不能作为一行代码使用?

Perl 为什么这个参考文件的定义不能作为一行代码使用?,perl,Perl,鉴于: 然后 但是 我不明白为什么。我遗漏了什么?有一个简单的取消引用规则涵盖了这一点。粗略地说: 符号后面的内容需要是它的正确引用,或者一个计算结果为该符号的块 特例 始终可以使用大括号中的数组引用来代替数组的名称。[……] 那么你的情况应该是这样的 my @list = @$($list0[1]); # gives an error message 不是索引[2],因为@list0有两个元素,所以空格仅用于可读性 尝试的@$$list0[2]是一个语法错误,首先是因为标识符变量名中不

鉴于:

然后

但是


我不明白为什么。我遗漏了什么?

有一个简单的取消引用规则涵盖了这一点。粗略地说:

符号后面的内容需要是它的正确引用,或者一个计算结果为该符号的块

特例

始终可以使用大括号中的数组引用来代替数组的名称。[……]

那么你的情况应该是这样的

my @list    = @$($list0[1]); # gives an error message
不是索引[2],因为@list0有两个元素,所以空格仅用于可读性

尝试的@$$list0[2]是一个语法错误,首先是因为标识符变量名中不允许出现$后面的字符,而$后面可能是什么字符

允许在$and后面有一个{}块,它将被计算,在这种情况下,它将产生一个标量引用,并被它前面的$UNERFERENCE;但是,第一个@将是错误的。如果推的话,这会变得一团糟。虽然确切的规则仍然有点模糊,但请参见标识符解析

@$listRef前面的语法通常是正确的。但是它引用了一个标量变量$listRef,它最好是一个数组引用,因为它被解引用到了一个数组中,而在这个例子中没有这样的东西——你有一个数组变量@listRef

所以使用要严格;实际上,这也将无法编译

请注意,取消对arrayref的引用以分配一个新数组是非常昂贵的,因为它必须复制所有元素并构造新的数组变量,而除非您确实需要一个副本,否则很少需要它。有了手头的阵列参考$ar,您可能需要的一切都很容易获得

my @list = @{ $list0[1] };
请参见切片和后缀引用切片

我怀疑这是否有效。这可能不会引发语法错误,但它肯定不会像您认为的那样。这一次

my @list    = @$@listRef;    # works
定义一个包含2个元素的数组,您可以访问

my @list0 = ( \@list2, \@list2 );
第三个要素。所以@listRef是一个数组,它包含一个未定义的元素。下面的代码也没有意义

除非zdim已经回答了这个纯学术性的问题,否则我假设您希望@list的第二个元素进入一个单独的数组,我会这样写

my @listRef = $list0[2];

你有很多不经意的参考,让我们来看看:

首先,您首先创建一个包含两个项目的列表,每个项目都是一个数组引用。将其存储在一个数组中:

my @list = @{ $list0[1] };
my @list0 = ( \@list2, \@list2 );
然后,请求索引为2的项,它是单个项,并将其存储在数组中:

my @list = @{ $list0[1] };
my @list0 = ( \@list2, \@list2 );
但是,没有索引为2的项,因为Perl索引从零开始。@listRef中的值未定义。不仅如此,您还请求了单个项,并将其存储在数组中而不是标量中。你可能不是这个意思

你说下面这句话行得通,但我不认为你知道这一点,因为即使你没有出错,它也不会给你期望的值。还有别的事情正在发生。您尚未声明或使用变量$listRef,因此Perl为您创建了它,并将其值设为undef。当您尝试取消引用它时,Perl使用自动激活来创建引用。如果从undef开始,Perl将在这个过程中为您创建一个引用结构:

该数组中没有任何内容,因此@list应该为空

修复该项以获取索引为1的最后一项,并修复该项,以便将引用分配给标量变量的单个值:

my @list    = @$listRef;    # works
这里很方便:

my $listRef = $list0[1];
您将获得以下输出:

use Data::Dumper;

my @list2 = qw(a b c);
my @list0 = ( \@list2, \@list2 );

my $listRef = $list0[1];

print Dumper($listRef);
Perl的一些特性可以捕捉这些类型的变量命名错误,并帮助您追踪问题。将以下内容添加到程序顶部:

$VAR1 = [
          'a',
          'b',
          'c'
        ];
接下来,你可能想看看我的书,里面解释了所有这些参考资料

而且,最近的PERL有一个新功能,名为,允许您从左到右写入解引用:

use strict;
use warnings;

这个问题并不完整,也不清楚预期的结果

OP尝试访问数组@list0中不存在的元素$list0[2]——数组中有索引为0和1的元素

也许@listRef在帖子中应该是$listRef

下面是我对所描述问题的看法

my @items = ( \@list2, \@list2 );

my @items_of_last_ref = $items[1]->@*;
输出

#!/usr/bin/perl

use strict;
use warnings;

use feature 'say';

my @list1 = qw/word1 word2 word3 word4/;
my @list2 = 1000..1004;

my @list0 = (\@list1, \@list2);

my $ref_array = $list0[0];

map{ say } @{$ref_array};

$ref_array = $list0[1];

map{ say } @{$ref_array};

say "Element: " . @{$ref_array}[2];
你需要

word1
word2
word3
word4
1000
1001
1002
1003
1004
Element: 1002
只要可以使用变量名,就可以使用计算结果为引用的块。这意味着获取数组元素的语法是

@{ $list0[1] }
也就是说

@NAME    # If you have the name
@BLOCK   # If you have a reference
my $array1 = [ 4..5 ];
my @array2 = @{ $array1 }

它们是等价的

当块中只有一个简单的标量$NAME或$block时,可以忽略卷曲。也就是说

@NAME    # If you have the name
@BLOCK   # If you have a reference
my $array1 = [ 4..5 ];
my @array2 = @{ $array1 }
相当于

@{ $array1 }
这就是为什么@$listRef可以工作的原因,也是为什么{$list0[1]}不能被简化的原因


请参阅。

您能分享错误消息吗?您能先更正第一行中的语法错误,以及$@$listRef。。。?这样我们才能真正知道我们在处理什么。这是不正确的,因为它在./x.py第11行出现语法错误,接近@$,谢谢更正,但是@$@。。。仍然是illega
l语法,因此使用@$@listRef它将不会编译。我猜不出你说的是什么意思…?语法正确,“@$@”的意思是,我不喜欢写正确的语法,决定把事情都搞错了。快的手指,慢的头脑,会犯很多类似的错误。很抱歉我的打字超出了我的思路,谢谢你提供了正确的语法。Gad,我真正的问题有三个列表,我只是不假思索地把实际的索引带了过来。@ArthurSchwarez好的,明白了,谢谢你的解释。我调整了这个答案,并做了一些更小的澄清
@{ $array1 }
@$array1