Perl中词法作用域和动态作用域有什么区别?

16
据我所知,my 运算符用于声明真正的词法作用域变量, 而使用 local 运算符声明变量则可以实现动态作用域。
有人能简要描述一下它们吗?
3个回答

14

local($x) 保存全局变量 $x 的旧值并为子例程的持续时间分配一个新值,该新值在从该子例程调用的其他函数中可见。这是在运行时完成的,因此被称为动态作用域。local() 总是影响全局变量,也称为包变量或动态变量。

my($x) 创建一个新变量,仅在当前子例程中可见。这是在编译时完成的,因此它被称为词法或静态作用域。my() 总是影响私有变量,也称为词法变量或(不当地)静态(作用域)变量。

请参阅Perl-FAQ's


6
"my($x)创建一个只在当前子程序中可见的新变量"这句话不准确。my创建的新变量只在当前代码块中可见,而子程序只是块的其中一种形式。您在定义local时也犯了类似的错误。 - Dave Cross
@O.D:如果{}周围没有花括号,则my作用域为整个文件。对于Perl,任何一个都是当前的代码块。 - w.k

10

6
我会添加一个快速示例。
$var = "Global";

sub inner {
    print "inner:         $var\n";
}

sub changelocal {
    my $var = "Local";
    print "changelocal:   $var\n";

    &inner
}

sub changedynamic {
    local $var = "Dynamic";
    print "changedynamic: $var\n";

    &inner
}

&inner
&changelocal
&changedynamic

这将产生以下输出(添加了注释)。
inner:         Global  # Finds the global variable.
changedynamic: Dynamic # Dynamic variable overrides global.
inner:         Dynamic # Find dynamic variable now.
changelocal:   Local   # Local variable overrides global.
inner:         Global  # The local variable is not in scope so global is found.

你可以将动态变量看作一种为你调用的函数掩盖全局变量的方式,而词法作用域变量只能在最近大括号内的代码中可见。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接