Lor*_*ein 11 arrays perl hash sigils
由于数组和散列只能包含Perl中的标量,为什么在访问数组或散列元素时必须使用$来告诉解释器该值是标量?换句话说,假设您有一个数组@myarray和一个哈希%myhash,为什么需要这样做:
$x = $myarray[1];
$y = $myhash{'foo'};
Run Code Online (Sandbox Code Playgroud)
而不只是做:
$x = myarray[1];
$y = myhash{'foo'};
Run Code Online (Sandbox Code Playgroud)
为什么上面的含糊不清?
如果除了那个地方的$之外,它不是非法的Perl代码吗?例如,Perl中的以下都不是非法的吗?
@var[0];
@var{'key'};
%var[0];
%var{'key'};
Run Code Online (Sandbox Code Playgroud)
hex*_*ten 22
我刚刚用过
my $x = myarray[1];
Run Code Online (Sandbox Code Playgroud)
在一个程序中,令我惊讶的是,这是我运行时发生的事情:
$ perl foo.pl
Flying Butt Monkeys!
Run Code Online (Sandbox Code Playgroud)
那是因为整个程序看起来像这样:
$ cat foo.pl
#!/usr/bin/env perl
use strict;
use warnings;
sub myarray {
print "Flying Butt Monkeys!\n";
}
my $x = myarray[1];
Run Code Online (Sandbox Code Playgroud)
所以myarray调用一个子例程,将它传递给包含单个元素1的匿名数组.
这是你需要在阵列访问上使用sigil的另一个原因.
zig*_*don 17
切片不是非法的:
@slice = @myarray[1, 2, 5];
@slice = @myhash{qw/foo bar baz/};
Run Code Online (Sandbox Code Playgroud)
我怀疑这是你需要指定是否要从哈希/数组中获取单个值的部分原因.
mor*_*itz 11
sigil为您提供容器的返回类型.因此,如果有东西开始@,你知道它返回一个列表.如果以它开头$,则返回标量.
现在,如果在sigil之后只有一个标识符($foo或者@foo,那么它是一个简单的变量访问.如果它后跟一个[,它是对数组的访问,如果它后跟一个{,则它是对哈希的访问.
# variables
$foo
@foo
# accesses
$stuff{blubb} # accesses %stuff, returns a scalar
@stuff{@list} # accesses %stuff, returns an array
$stuff[blubb] # accesses @stuff, returns a scalar
# (and calls the blubb() function)
@stuff[blubb] # accesses @stuff, returns an array
Run Code Online (Sandbox Code Playgroud)
一些人类语言具有非常相似的概念.
然而,许多程序员发现令人困惑,因此Perl 6使用了一个不变的sigil.
一般来说,Perl 5编译器想要在编译时知道某些内容是在列表中还是在标量上下文中,因此如果没有前导符号,则某些术语会变得模棱两可.
这是有效的Perl : @var[0]. 它是长度为1的数组切片.@var[0,1]将是一个长度为2的数组切片.
@var['key']是无效的Perl,因为数组只能用数字索引,而其他两个(%var[0] and %var['key'])不是有效的Perl,因为散列片使用{}来索引散列.
@var{'key'}并且@var{0}都是有效的哈希切片.显然,采用长度为1的切片是不正常的,但它肯定是有效的.
有关在Perl中进行切片的更多信息,请参阅perldata perldoc的切片部分.
我可以想到一种方式
$x = myarray[1];
Run Code Online (Sandbox Code Playgroud)
是不明确的 - 如果你想要一个名为m的数组怎么办?
$x = m[1];
Run Code Online (Sandbox Code Playgroud)
除了正则表达式匹配之外,你怎么能说出来呢?
换句话说,语法是帮助Perl解释器,好吧,解释!
在Perl 5中(要在Perl 6中进行更改),sigil表示表达式的上下文.
$hash{key}.$array[0].然而,正如zigdon指出的那样,切片是合法的.他们在列表上下文中解释这些表达式.
@hash{key}工作中的1个值的列表但是更大的列表也可以使用@hash{qw<key1 key2 ... key_n>}.
你想要一个阵列中的几个插槽@array[0,3,5..7,$n..$n+5]工作
@array[0] 是一个大小为1的列表. 没有"哈希上下文",所以既没有%hash{@keys}也没有%hash{key}意义.
所以你有"@"+ "array[0]"<=> <sigil = context> + <indexing expression>作为完整的表达式.