考虑下一个。有一个列表
qw(a b c);
现在,将LIST分配给无名(匿名)ARRAY
[ qw(a b c) ]
所以下一个
use 5.016;
use warnings;
use diagnostics;
my $x = [ qw(a b c) ];
say ref $x; #ARRAY - the $x is an ARRAY reference, and
say $x->[1]; #prints "b", and
say [ qw(a b c) ]->[1]; #works too
但现在发生了什么?
use 5.016;
use warnings 'all';
use diagnostics;
say ${[ qw(a b c) ]}[1];
它打印b
,但
my $y = ${[ qw(a b c) ]};
是一个错误,
Not a SCALAR reference at pepe line 6 (#1)
(F) Perl was trying to evaluate a reference to a scalar value, but found
a reference to something else instead. You can use the ref() function
to find out what kind of ref it really was. See perlref.
Uncaught exception from user code:
Not a SCALAR reference at pepe line 17.
所以,什么意思是建筑$ {....}
say
中“起作用”(打印匿名数组的第二个元素),但不明白为什么来自diagnostics
的提示不是很有帮助,因为当我无法分配时我应该如何使用ref
?我错过了perlref
?
答案 0 :(得分:10)
${ EXPR1 }[ EXPR2 ]
是一个数组索引取消引用。它返回由EXPR2
返回的引用引用的数组EXPR1
返回的索引处的元素。
${ $array_ref }[ ... ]
是数组引用,因为$array[...]
是数组。
${ EXPR }
或[
跟踪的 {
是标量解除引用。它返回由EXPR
返回的引用引用的标量。
${ $scalar_ref }
是标量引用,因为$scalar
是标量。
正如您所看到的,在处理引用时,您可以使用与通常相同的语法,除了用{$ref}
替换变量的名称(保留前导符号)。
因此,@{ $array_ref }
是数组引用,因为@array
是数组。
say @{[ qw(a b c) ]};
这是我早期帖子Mini-Tutorial: Dereferencing Syntax中图表的精髓。另见:
哎呀,我以为你有
say ${[ qw(a b c) ]}; # Want to print a b c
你有
my $y = ${[ qw(a b c) ]};
你想要
my $y = [ qw(a b c) ];
[]
创建一个数组和对该数组的引用,并返回后者,有点像
my $y = do { my @anon = qw(a b c); \@a };
答案 1 :(得分:4)
给定数组@arr
和arrayref $aref = \@arr
,然后在以下表达式组中,所有行都是等效的:
访问整个阵列:
@ arr
@{$aref}
访问数组中的单个标量:
$ arr [$i]
${$aref}[$i]
$ aref->[$i]
访问一条条目:
@ arr [$i .. $j]
@{$aref}[$i .. $j]
(包含空格用于对齐,不建议用于实际代码。)
${}
,@{}
,...是外接取消引用运算符。但是,访问单个标量会将标记从%
或@
更改为$
。没有参考,这是完全有道理的。有了它们,它只是稍微复杂一点,直到你阅读perlreftut
(特别是两个参考使用规则)。
答案 2 :(得分:1)
使用
${$ar}[0]
你对perl说:将$ar
作为arrayref
并将数组中的第一个元素返回给引用$ar
点。
施工
${$sr}
你对perl说:将$sr
作为SCALAR REF
并将标量的值返回到引用$sr
点。
因此,从评论中回答你的问题:当$ ar是数组引用时,$ {$ ar}是什么?是:
当$ ar是$ array-ref时,$ {$ ar}是 错误 ,
因为你说perl - 采用标量引用,但$ ar不是标量引用(它是arrayref)。
下一个示例清楚地显示了您的构造:
use 5.012;
use warnings;
my @arr = qw(a b c);
my $aref = \@arr;
my $myval = "VALUE";
my $sref = \$myval;
say $aref->[0];
say ${$aref}[0];
say ${$sref}; #your construction - here CORRECTLY points to an scalar
#say ${$aref} #ERROR because the ${$xxx} mean: take scalar ref, but the $aref is array ref.