2
for my $n (1, 2) {
  sub_example();
}

sub sub_example {
  my $bar = 1 if 1 == 2;
  if ($bar) {
     print "hahha, you see\n";
  }
  else {
     $bar = 1;
  }
}

所以我的问题是为什么在第二次循环迭代中定义了 $bar ?

4

2 回答 2

9

您正在利用一个奇怪的错误(在 5.30 中正式弃用并计划成为一个致命错误),它涉及my在语句中声明一个词法 ( ) 变量,其中语句修饰符条件为假。

之所以会这样,是因为my $bar = 1;基本上有两个功能。它有一个编译时功能,就是为一个变量保留词法板中的空间,并$bar与该空间关联;并且它有一个运行时函数,即在控制流到达语句时1进行赋值(没有赋值的语句也有这两个效果,除了它在运行时赋值)。$barmymy $foo;undef

当您使用 false 条件控制语句时my $bar = 1 if 1 == 2;编译时函数保持完全相同,但运行时函数被阻止使用 false 条件运行,这意味着该存储中的任何值都将被重新使用,每次代码到达该点时都不会被重新分配。这几乎但不完全像使用state变量一样产生效果。这是一个很酷的技巧,但不推荐用于任何严肃的用途,而且正如我所提到的,它将在即将发布的 perl 版本中失效,这是不依赖它的另一个原因。

于 2018-06-05T09:17:31.360 回答
6

你永远不应该使用mywith 语句修饰符。这种构造的行为是未定义的(参见perlsyn)。

当前的实现不会清除在子例程的上一次运行中分配给变量的值,但不能保证该行为会保持不变(事实上,它不会:参见perldeprecation)。

于 2018-06-05T09:17:22.347 回答