【问题标题】:How does Perl implement global reference to private variable of a subroutine?Perl 如何实现对子程序私有变量的全局引用?
【发布时间】:2016-11-28 15:11:43
【问题描述】:

我有两个代码部分,分别是 Perl 和 C。这是关于 Perl 的 my 变量和 C 的自动变量。在某种程度上,它们非常相似,因为它们每次进入函数时都会被初始化。但是 Perl 可以引用子程序的my 变量,如果这样做,C 会得到随机值,因为函数调用堆栈在返回后被破坏。有人知道 Perl 是如何实现这个功能的吗?不可能让每个子程序调用堆栈都保持不变,是不是 Perl 分配了在“数据段”中的子程序中创建的每个 my 变量(与堆栈相比)?

Perl 代码:

use strict;
use warnings;

my $ref;

sub func
{
    my $str = "hello";
    $ref = \$str;
}
func;
print "value is ";
print "${$ref}\n";

C 代码:

#include <stdio.h>

int *pi;

void func(void)
{
    int j = 9;
    pi = &j;
}

int main(void)
{
    func();
    printf("value is ");
    printf("%d\n", *pi);
    return 0;
}

谢谢,

【问题讨论】:

    标签: perl reference return subroutine


    【解决方案1】:

    您将全局变量设置为引用函数中本地创建的一些数据。

    在 Perl(一种“托管内存”语言)中,这将是一个引用计数的“对象”(松散地使用术语,因为它在这里是一个字符串),在所有引用消失之前不会被垃圾收集。

    在 C 中,这只是一个内存地址,您必须自己确保它仍然有效(并且不指向函数一返回就已经回收的堆栈空间)。

    【讨论】:

    • 嗨@Thilo 要使引用计数可用于子例程的变量,这是否意味着如果引用 my 变量将存储在数据段中?如果不被引用,则存储在堆栈中?
    • 我认为 Perl 中的所有变量都分配在托管堆区域中,而不是自动堆栈中。如果子例程退出,所有局部变量的引用计数将减少,通常变为零,除非您为其创建另一个引用。这就像在 Java 中使用对象(与原语相反,原语可以堆栈分配,更像是在您的 C 示例中)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-28
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 2021-11-13
    • 1970-01-01
    • 2013-10-06
    相关资源
    最近更新 更多