因为阵列和哈希只能含有标量在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'};
有帮助吗?

解决方案

切片不是非法的:

@slice = @myarray[1, 2, 5];
@slice = @myhash{qw/foo bar baz/};

我怀疑这是你需要指定是否要从哈希/数组中获取单个值的部分原因。

其他提示

我刚刚用过

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的另一个原因。

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编译器想要在编译时知道某些内容是在列表中还是在标量上下文中,因此如果没有前导符号,某些术语就会变得模棱两可。

这是有效的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的切片部分

人们已经指出你可以有切片和上下文,但是可以将变量和其他东西分开。您不必知道所有关键字或子例程名称来选择合理的变量名称。这是我在其他语言中想念Perl的重大事项之一。

我可以想到一种方式

$x = myarray[1];

是不明确的 - 如果你想要一个名为m的数组怎么办?

$x = m[1];

除了正则表达式匹配之外,你怎么能说出来呢?

换句话说,语法是帮助Perl解释器,好吧,解释!

在Perl5(将改变在Perl6)符号的指示 上下文 你的表达。

  • 你想要一个特定的标出来的散列,所以它的 $hash{key}.
  • 你想要的价值的一个特定的老虎的阵列,所以它的 $array[0].

然而,正如指出的zigdon, 切片 是合法的。他们解释那些表达形式在一个 列表 上下文。

  • 你想要一个列表1的数值在哈希 @hash{key} 工作
  • 但是还有更大的清单的工作,以及像 @hash{qw<key1 key2 ... key_n>}.

  • 你想要几个插槽出的一系列 @array[0,3,5..7,$n..$n+5] 工作

  • @array[0] 是一个名单的尺寸1.

有没有"散列方面",因此既没有 %hash{@keys} 也不 %hash{key} 具有意义。

所以你必须 "@" + "array[0]" <=> < 印记=背景下>+ < 索引表达>作为完整的表达。

印记提供了背景下的访问:

  • $ 指标下的(a scalar 变量或单个元件的散列或一系列)
  • @ 装置名单上下文中(a系列,或一片 散列或一系列)
  • % 是一个整个的哈

在Perl 5中你需要sigils($和@),因为裸字标识符的默认解释是子程序调用的默认解释(因此在大多数情况下无需使用<!> amp;)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top