【问题标题】:Weak References in PerlPerl 中的弱引用
【发布时间】:2015-06-24 08:40:35
【问题描述】:

如何在perl中创建对对象的弱引用,这样当对象超出范围时,引用计数就会被释放?
我尝试使用 DESTROY 子来打破循环引用。

sub DESTROY{  
my $p = shift;  
delete $p->{__tree__};  
delete $p->{tokenizers};  
delete $p->{toke};  
}

请帮忙。

【问题讨论】:

    标签: perl garbage-collection


    【解决方案1】:

    您不能“调用”destroy - 这里的问题是 perl 对引用计数起作用 - 对事物的每个引用都会被计数,并且 当引用计数降至零时,它可以被释放/销毁/垃圾收集。

    DESTROY 是一个特殊的方法,它在对象内调用以执行清理任务当这种情况发生时。它不会删除对象,它只是让它在它死后做一些最后的整理。

    看看Scalar::Util 模块。它包括 weaken 方法,该方法完全符合您的要求。

    左值 $ref 将变成弱引用。这意味着它不会对它引用的对象进行引用计数。此外,当该对象的引用计数达到零时,该引用将设置为 undef。此函数改变作为其参数传递的左值并且不返回任何值。

    这对于保留引用的副本很有用,但您不想阻止对象在通常的时间被销毁。

    【讨论】:

      【解决方案2】:

      来自perldoc

      您可以通过创建“弱引用”来破坏循环引用。弱引用不会增加变量的引用计数,这意味着对象可能会超出范围并被销毁。您可以使用 Scalar::Util 模块导出的弱化函数来弱化引用。

      以下是我们如何使第一个示例更安全的方法:

      use Scalar::Util 'weaken';
      my $foo = {};
      my $bar = { foo => $foo };
      $foo->{bar} = $bar;
      weaken $foo->{bar};
      

      $foo$bar 的引用已被削弱。当$bar 变量超出范围时,它将被垃圾回收。下次查看$foo->{bar} key 的值时,将是undef

      这个远距离的动作可能会让人困惑,所以你应该小心使用弱化。您应该在将超出范围的变量中削弱引用first。这样,寿命更长的变量将包含预期的引用,直到它超出范围。

      【讨论】:

      • 虽然效果很好,但除了使用 Scalar::Util 'weaken' 之外还有其他解决方案吗?
      • 你可以重新发明轮子。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多