当前位置:  开发笔记 > 编程语言 > 正文

为什么在访问Perl中的数组和哈希元素时需要$?

如何解决《为什么在访问Perl中的数组和哈希元素时需要$?》经验,为你挑选了7个好方法。

由于数组和散列只能包含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'};

hexten.. 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> hexten..:

我刚刚用过

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



2> zigdon..:

切片不是非法的:

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

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



3> moritz..:

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



4> nohat..:

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



5> brian d foy..:

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



6> Paul Dixon..:

我可以想到一种方式

$x = myarray[1];

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

$x = m[1];

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

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



7> Axeman..:

在Perl 5中(要在Perl 6中进行更改),sigil表示表达式的上下文.

你想要一个哈希的特定标量,所以它是$hash{key}.

你想要一个特定插槽的值超出一个数组,所以它是$array[0].

然而,正如zigdon指出的那样,切片是合法的.他们在列表上下文中解释这些表达式.

您需要哈希@hash{key}工作中的1个值的列表

但是更大的列表也可以使用@hash{qw}.

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

@array[0] 是一个大小为1的列表.

没有"哈希上下文",所以既没有%hash{@keys}也没有%hash{key}意义.

所以你有"@"+ "array[0]"<=> + 作为完整的表达式.

推荐阅读
黄晓敏3023
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有