为什么$ foo

编程入门 行业动态 更新时间:2024-10-26 01:29:45
本文介绍了为什么$ foo-> {bar}会自动恢复,而%$ foo不能恢复?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有以下代码:

$headers; some_sub( %$headers );

致电some_sub时出现错误:

不能在...处使用未定义的值作为HASH引用

Can't use an undefined value as a HASH reference at ...

但是类似的代码不会产生错误:

But similar code does not produce an error:

$headers->{ x };

为什么第一个示例中的自动生存功能与第二个示例中的自动生存功能不同?

Why doesn't autovivification work the same way in the first example as it does in the second?

UPD

我由 @ThisSuitIsBlackNot 记录.我真的要问:

I noted by @ThisSuitIsBlackNot. I really ask:

为什么我的$ h; $ h-> {foo}有效,而我的$ h; %$ h没有

why my $h; $h->{foo} works and my $h; %$h doesn't

UPD 真实代码:

UPD The real code:

my $email = Email::Simple->create(() ,header => [() ,To => $address ,From => $cnf->{ from } ,Subject => $subject ,'Content-Type' => 'text/html; charset="utf8"' ,%$headers ] ,body => $body );

推荐答案

注意问题中添加的代码说明了为什么不进行自动生存.

Note Code added to the question demostrates why autovivification doesn't happen.

短您的子项使用一个列表(哈希),该列表具有一个匿名数组作为元素–.并且%$headers埋在该数组中.这是 anon数组 它是标量的别名,因此不需要%$headers可修改.这样就不会发生自动生存,并且由于在未定义的引用上尝试取消引用,您会遇到以下致命的运行时错误.

Short Your sub takes a list (hash) which has an anonymous array as an element – and %$headers is buried in that array. It is the anon array that is the scalar aliased to, thus there is no requirement for %$headers to be modifiable. Thus no autovivification happens, and you get the fatal runtime error described below, as dereferencing is attempted on an undefined reference.

%$ref在左值上下文中使用时会自动保留.这可能会在子调用中发生,请参见下文.

A %$ref autovivifies when used in lvalue context. This may happen in a sub call, see below.

您显示的错误是由于使用了未定义的引用.例如,语句

The error you show is due to the use of an undefined reference. For example, the statement

my %hash = %{ $ref };

尝试从存储在$ref中的内存位置复制哈希并将其分配给%hash.符号%hash是在编译时创建的,但是如果在$ref上未找到哈希,或者在$ref中没有任何内容,则会出现错误.这里没有自动生存.启用use strict

attempts to copy a hash from the memory location stored in $ref and assign it to %hash. The symbol %hash is created at compile time, but if no hash is found at $ref or if there is nothing in $ref, we get an error. No autovivification happens here. With use strict in effect

perl -wE'use strict; my $h; my %h = %$h; say $h'

这会引发致命的运行时错误

this throws the fatal runtime error

Can't use an undefined value as a HASH reference at -e line 1.

当eval -ed要生存下来

perl -wE'use strict; my $h; my %h = eval { %$h }; say $h; say "hi"'

它将显示有关"未初始化的值",空行和hi的警告.没有哈希值.

it prints a warning about "uninitialized value", an empty line, and then hi. No hash.

但是,当在子例程调用中用作参数时,它会自动生存

However, when used as an argument in a subroutine call it autovivifies

perl -wE'use strict; sub tt { 1 }; my $h; tt( %$h ); say $h'

,因为这将打印行HASH(0x257cd48),而没有警告或错误.

as this prints the line HASH(0x257cd48), without warnings or errors.

当在左值上下文中使用了被取消引用的对象时,会发生自动生存,这意味着它需要可修改.在子例程调用中,其原因是函数的参数在@_中具有别名,因此必须可以对其进行修改.相同的别名需求使其在foreach循环中发生,而keys重置哈希迭代器.参见这篇文章和这篇文章和此信息.

The autovivification happens when a dereferenced object is used in lvalue context, which means that it needs to be modifiable. In a subroutine call the reason for this is that arguments to a function are aliased in @_ so it must be possible to modify them. The same aliasing need makes it happen in a foreach loop, while keys resets the hash iterator. See this post and this post and this post.

感谢 ThisSuitIsBlackNot 以获得解释和链接.

Thanks to ThisSuitIsBlackNot for explanation and links.

在您的情况下,%$ref作为匿名数组的元素传递,因此没有别名(arrayref本身是).因此,自动生存无法发挥作用,您会收到该错误.

In your case the %$ref is passed as an element of an anonymous array, and is thus not aliased (the arrayref itself is). So autovivication does not kick in and you get that error.

关于自动生存,来自术语表

在Perl中,存储位置(左值)会根据需要自发生成自身,包括创建任何硬参考值以指向下一级存储.赋值$a[5][5][5][5][5] = "quintet"可能会创建五个标量存储位置,外加指向四个新匿名数组(以保存最后四个标量位置)的四个引用(在前四个标量位置中).但是,自动生存的关键是您不必为此担心.

In Perl, storage locations (lvalues) spontaneously generate themselves as needed, including the creation of any hard reference values to point to the next level of storage. The assignment $a[5][5][5][5][5] = "quintet" potentially creates five scalar storage locations, plus four references (in the first four scalar locations) pointing to four new anonymous arrays (to hold the last four scalar locations). But the point of autovivification is that you don’t have to worry about it.

例如,还参见 Article 中的文章

Also see, for example, an article from Effective Pearler

更多推荐

为什么$ foo

本文发布于:2023-10-16 15:58:48,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1498047.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:foo

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!