如何解决Perl 散列的散列原理
我决定尝试一下 Perl,我偶然发现了一种似乎有效的语言结构,但我简直不敢相信。我想这背后有一些道理,所以我决定问一个问题。
采用以下 Perl 代码:
%data = ('John Paul' => ('Age' => 45),'Lisa' => 30);
print "\$data{'John Paul'} = $data{'John Paul'}{'Age'}\n";
print "\$data{'Lisa'} = $data{'Lisa'}\n";
我的目的是检查散列的散列是如何工作的。上面的代码打印:
$data{'John Paul'} =
$data{'Lisa'} =
要使其成为需要的有效散列值:
%data = ('John Paul' => {'Age' => 45},'Lisa' => 30);
结果是:
$data{'John Paul'} = 45
$data{'Lisa'} = 30
有谁知道:
- 为什么存在不一致且内部散列需要
{}
而不是()
? - 当内部哈希值是
()
而不是{}
时,为什么我没有收到错误或警告出现问题?很容易犯这样的错误。此外,('Age' => 45)
不仅会破坏'John Paul'
的值,还会破坏'Lisa'
的值。我无法想象在数千行代码的项目中搜索这种“错误”。
解决方法
( 'John Paul' => ( 'Age' => 45 ),'Lisa' => 30 )
只是另一种写作方式
'John Paul','Age',45,'Lisa',30
Parens 不创建任何数据结构;它们只是像 (3+4)*5
一样影响优先级。我们不写的原因
my %h = a => 4;
或等价物
my %h = 'a',4;
是它会被解释为
( my %h = 'a' ),4;
创建哈希的是 my %data
,而不是括号。赋值的右侧只是在堆栈上放置了任意数量的标量,而不是散列。赋值运算符将这些标量添加到哈希中。
但有时,我们想创建一个匿名哈希。这就是 {}
的用武之地。
my %data = ( 'John Paul' => { 'Age' => 45 },'Lisa' => 30 );
基本上等价于
my %anon = ( 'Age' => 45 );
my %data = ( 'John Paul' => \%anon,'Lisa' => 30 );
请注意,\%anon
返回标量,即对哈希的引用。这与 ( 'John Paul' => \%anon,'Lisa' => 30 )
和 'John Paul' => \%anon,'Lisa' => 30
返回的四个标量有着根本的不同。
为什么不统一,内部散列需要 {}
而不是 ()
?
这个问题的一个基本前提是错误的:哈希不需要 ()
。例如,以下是完全有效的:
my %h1 = 'm'..'p';
sub f { return x => 4,y => 5 }
my %h2 = f();
my %h3 = do { i => 6,j => 7 };
()
与哈希无关。缺乏统一性源于缺乏平行性。一种使用 {}
创建哈希。一种使用 ()
来覆盖优先级。
由于括号只影响优先级,所以可以使用
my %data = ( 'John Paul' => ({ 'Age' => 45 }),'Lisa' => 30 ); # ok (but weird)
这与以下非常不同:
my %data = ( 'John Paul' => ( 'Age' => 45 ),'Lisa' => 30 ); # XXX
当内部散列使用 () 而不是 {} 时,为什么我没有收到错误或警告有问题?
不仅使用 ()
有效,通常还需要在包含逗号的表达式周围使用 ()
。那么它到底应该在什么时候发出警告呢?关键是这应该是警告还是 perlcritic
发现的东西,至少乍一看是有争议的。后者肯定会找到这个,但我不知道它是否存在规则。
为什么不统一,内部散列需要 {} 而不是 ()?
对散列的赋值是一个标量列表(在键和值之间交替)。
你不能有一个散列(因为它不是标量)作为那里的值,但你可以有一个散列引用。
列表变得扁平。
当内部散列使用 () 而不是 {} 时,为什么我没有收到错误或警告有问题?
因为您没有使用 the use strict; use warnings;
pragmas 开启它们(默认情况下由于向后兼容性太差而关闭,但将是 on by default in Perl 7)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。