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