gpt4 book ai didi

perl - 了解 perl 的赋值或运算符与赋值和逻辑或运算符的组合之间的行为差​​异

转载 作者:行者123 更新时间:2023-12-04 15:56:21 25 4
gpt4 key购买 nike

今天,当我在 perl 中遇到以下行为时,我感到很惊讶:

sub f { die if %{ $_[0] }; 42 }
my %h;
$h{x} ||= f(\%h); # we die. $_[0] references a hash with an 'x' key during f's run-time

相比之下,给定相同的设置,以下语句的行为不同。

$h{x} = $h{x} || f(\%h); # $h{x} is now 42

赋值或与赋值和逻辑或的组合之间的这种潜在差异是否记录在某处?

如果这是由于自动激活引起的,是不是 autovivification 模块中的一个错误或缺失的功能,它似乎无法检测到这个特定构造中的自动激活?

最佳答案

关键信息:

  • ||||= 是短路的,因此它们必须先评估其左侧,然后再评估其右侧。 (这允许 f() || die()。)

  • = 在其左侧计算其右侧操作数。 (这允许 $x = f($x)。)

  • ||= 的左侧仅计算一次。

  • 除非必要(即在左值上下文中),否则不会在访问时激活(创建)哈希元素。


让我们看看$h{x} = $h{x} || f(\%h);.

综上所述,我们得出以下结论:

  • 只有最左边的 $h{x} 需要激活元素。
  • 最左边的 $h{x}f 返回后计算。

让我们看看$h{x} ||= f(\%h);

综上所述,我们得出以下结论:

  • $h{x} 必须在调用 f 之前计算。
  • 评估 $h{x} 必须产生一个可修改的值,因此它必须激活 $h{x}

左值上下文

  • 赋值运算符的左侧(包括 ||=)。
  • 前/后递增/递减的操作数。
  • \ 的操作数。
  • Foreach 循环列表表达式(因为 $_ = uc($_) for @a;)。
  • 子程序参数(因为 sub ucip { $_[0] = uc($_[0]) }),但请参阅下面的“一个异常(exception)”。
  • 其他?

一个异常(exception)

如果你将 $h{x} 传递给一个 sub,Perl 实际上传递了一个神奇的标量来代替 $h{x}。这样做是为了尽可能防止活体化。它并不便宜,但避免了很多令人讨厌的意外。

Perl 可以使用相同的机制在 $h{x} ||= f(\%h); 中延迟激活,但这不值得付出代价。

关于perl - 了解 perl 的赋值或运算符与赋值和逻辑或运算符的组合之间的行为差​​异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70100892/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com