由于数组和散列只能包含Perl中的标量,为什么在访问数组或散列元素时必须使用$告诉解释器该值是标量?换句话说,假设您有一个数组@myarray
和一个哈希%myhash
,为什么还需要这样做:
$x = $myarray[1];
$y = $myhash{'foo'};
而不仅仅是:
$x = myarray[1];
$y = myhash{'foo'};
为什么上面的含糊不清?
如果除了那个地方的$之外它不是非法的Perl代码吗?例如,Perl中是不是以下都是非法的?
@var[0];
@var{'key'};
%var[0];
%var{'key'};
答案 0 :(得分:22)
我刚刚用过
my $x = myarray[1];
在一个程序中,令我惊讶的是,这是我运行时发生的事情:
$ perl foo.pl
Flying Butt Monkeys!
那是因为整个程序看起来像这样:
$ cat foo.pl
#!/usr/bin/env perl
use strict;
use warnings;
sub myarray {
print "Flying Butt Monkeys!\n";
}
my $x = myarray[1];
因此,myarray调用一个子例程,向它传递一个包含单个元素的匿名数组的引用,1。
这是你需要在数组访问上使用sigil的另一个原因。
答案 1 :(得分:17)
切片不是非法的:
@slice = @myarray[1, 2, 5];
@slice = @myhash{qw/foo bar baz/};
我怀疑这是你需要指定是否要从哈希/数组中获取单个值的部分原因。
答案 2 :(得分: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
有些人类语言的概念非常相似。
然而,许多程序员发现令人困惑,因此Perl 6使用了一个不变的sigil。
一般来说,Perl 5编译器想要在编译时知道某些内容是在列表中还是在标量上下文中,因此如果没有前导符号,某些术语就会变得模棱两可。
答案 3 :(得分:9)
这是有效的Perl:@var[0]
。它是长度为1的数组切片。 @var[0,1]
将是长度为2的数组切片。
@var['key']
无效Perl,因为数组只能用数字索引,而且
另外两个(%var[0] and %var['key']
)是无效的Perl,因为散列片使用{}来索引散列。
@var{'key'}
和@var{0}
都是有效的哈希切片。显然,采用长度为1的切片是不正常的,但它肯定是有效的。
有关在Perl中进行切片的详细信息,请参阅the slice section of perldata perldoc。
答案 4 :(得分:9)
人们已经指出你可以有切片和上下文,但是可以将变量和其他东西分开。您不必知道所有关键字或子例程名称来选择合理的变量名称。这是我在其他语言中想念Perl的重大事项之一。
答案 5 :(得分:7)
我可以想到一种方式
$x = myarray[1];
是不明确的 - 如果你想要一个名为m的数组怎么办?
$x = m[1];
除了正则表达式匹配之外,你怎么能说出来呢?
换句话说,语法是帮助Perl解释器,好吧,解释!
答案 6 :(得分:6)
在Perl 5中(要在Perl 6中进行更改),sigil表示表达式的 context 。
$hash{key}
。 $array[0]
。 然而,正如zigdon所指出的,切片是合法的。他们在 list 上下文中解释这些表达式。
@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]"
&lt; =&gt; &LT; sigil = context&gt; +&lt;索引表达式&gt;作为完整的表达。
答案 7 :(得分:4)
sigil提供访问的上下文:
$
表示标量上下文(标量
变量或散列或数组的单个元素)@
表示列表上下文(整个数组或一个切片)
哈希或数组)%
是一个完整的哈希答案 8 :(得分:4)
在Perl 5中你需要sigils($和@),因为裸字标识符的默认解释是子程序调用的默认解释(因此在大多数情况下不需要使用&amp;)。