perl哈希初始化语法

perl哈希初始化语法,perl,hash,initialization,Perl,Hash,Initialization,我正在读一个perl脚本,有一行我不完全理解 代码如下所示: sub foo { package CFG; %hash1 = ...; } sub bar { my %hash2 = %{CFG::hash1}; } 这是我的问题:为什么%hash2被初始化为%{CFG::hash1},而不仅仅是我的%hash2=CFG::hash1。这两者有什么区别 这里发生了几件事。第一,来自: 语法中没有其他解释的单词将被处理 好像它是一个带引号的字符串。这些被称为“空话”。如同

我正在读一个perl脚本,有一行我不完全理解

代码如下所示:

sub foo {
    package CFG;
    %hash1 = ...;
}

sub bar {
   my %hash2 = %{CFG::hash1};
}

这是我的问题:为什么%hash2被初始化为%{CFG::hash1},而不仅仅是我的%hash2=CFG::hash1。这两者有什么区别

这里发生了几件事。第一,来自:

语法中没有其他解释的单词将被处理 好像它是一个带引号的字符串。这些被称为“空话”。如同 文件句柄和标签,一个完全由小写字母组成的裸字 字母可能与将来保留的单词冲突[…]

有些人可能希望完全取缔空话。如果你说

use strict 'subs';  
然后是任何不会被解释为子程序调用的裸字 而是生成编译时错误

此外,如果启用pragma,如果尝试使用奇数个元素初始化哈希,则会收到警告。发件人:

散列赋值中奇数个元素
(W杂项)您指定了 要初始化哈希的奇数个元素,这是奇数,因为 散列以键/值对的形式出现

最后,来自:

不是那么符号化的引用
符号引用周围的括号可以 只需将标识符或变量名与其他名称隔离 表达式的,就像它们在字符串中总是有的一样。对于 例如

$push = "pop on ";  
print "${push}over";
一直打算打印“弹出式”,即使推 是一个保留字。 这是广义的,没有封闭双精度 引用,以便

print ${push} . "over";  
也会有同样的效果。此构造不被视为 使用严格参照时的符号参照:

所以当你写作时:

my %hash2 = CFG::hash1;
您首先尝试使用奇数个元素初始化哈希,如果启用了
警告
,您将得到一个关于此的警告。其次,由于没有名为
CFG::hash1
sub
,因此后者是一个未定义的裸字,如果使用
strict
pragma,则会出现编译时错误

Bareword "CFG::hash1" not allowed while "strict subs" in use
最后,将
%hash2
声明为
%CFG::hash1
%{CFG::hash1}
是等效的。(但请注意,使用
%{…}
也可以编写示例
%{CFG::hash1()}
,然后我们将尝试调用名为
CFG::hash1()
,并使用其返回值作为哈希键。)

结论


语法
my%h1=%h2
(或
my%h1=%{h2}
)将哈希
%h2
复制到
%h1
。您问题中的另一个语法:
my%h1=h2
创建一个新哈希(使用一个具有未定义值的键,如上所述)。

您可以编写my
%hash2=CFG::hash1
(前提是您没有使用严格的pragma),但这将设置
%hash2=(CFG::hash1,unde)
其中
CFG::hash1
被解释为一个空字,并成为
%hash2
中的一个键。如果要将哈希值
%CFG::hash1
复制到
%hash2
中,请按照当前在
bar()
中执行的操作:
my%hash2=%CFG::hash1
谢谢。在你评论的结尾,你不是想写“我的%hash2=%{CFG::hash1};”(带花括号)?我认为在这里写
%CFG::hash1
%{CFG::hash1}
没有区别。但是,如果定义了一个
sub
CFG::hash1()
,例如
sub-CFG::hash1{return“a”}
,那么赋值
%hash2=CFG::hash1
将设置
%hash2=(a=>unde)
,尽管我们的新perl学习者可能还没有达到需要知道这一点,值得一提的是,从技术上讲,将一个散列复制到另一个散列是一种“浅层”复制,因为复制包含引用的值。因此,在
%h2=%h1
之后,两个哈希现在将具有相同的键和值,如果
%h1
中的任何标量值实际上是(“硬”)引用,而不仅仅是字符串和/或数字,则包括(如果适用)共享引用。