我和Perl之间的区别是什么?

Nat*_*man 184 perl scope

我知道myPerl中有什么.它定义了一个仅存在于定义它的块范围内的变量.怎么our办?有our什么不同my

Fra*_*ier 213

好问题:如何our区别my和做our什么?

综上所述:

从Perl 5开始提供,my是一种声明:

  • 非包装变量,即
  • 私人的,
  • 新的,
  • 非全局变量,
  • 与任何包裹分开.这样就无法以形式访问变量$package_name::variable.


另一方面,our变量是:

  • 包变量,因此自动
  • 全局变量,
  • 绝对不是私人的,
  • 它们也不一定是新的; 和他们
  • 可以使用限定名称空间在包(或词法范围)外部访问,如$package_name::variable.


声明变量our允许您预先声明变量以便在use strict不使用拼写错误警告或编译时错误的情况下使用变量.从Perl 5.6开始,它已经取代了过时的use vars,它只是文件范围的,而不是按字面顺序排列our.

例如,$x内部变量的正式限定名称package main$main::x.当脚本使用或时,声明our $x允许您$x在声明的范围内使用裸变量而不会受到惩罚(即,没有产生错误).范围可能是一个,两个或更多个包,或一个小块.use strictuse strict "vars"

  • @Nathan Fellman,`local`不会创建变量.它根本不涉及"我的"和"我们的".`local`暂时备份变量的值并清除其当前值. (17认同)
  • 那么我们与本地有何不同? (2认同)
  • `our` 变量不是包变量。它们不是全局范围的,而是词法范围的变量,就像 `my` 变量一样。您可以在以下程序中看到:`package Foo; 我们的 $x = 123;包吧;说 $x;`。如果你想“声明”一个包变量,你需要使用`use vars qw( $x );`。`our $x;` 声明了一个词法范围的变量,该变量别名为编译 `our` 的包中的同名变量。 (2认同)

bub*_*ker 60

来自cartman和Olafur的PerlMonks和PerlDoc链接是一个很好的参考 - 下面是我的总结:

my{}如果不是在{}s中,则变量在由同一文件定义的单个块内的词法范围内.它们不能从相同词法范围/块之外定义的包/子例程访问.

our变量在包/文件中作用域,并且可以从任何代码userequire包/文件中访问 - 通过在相应的名称空间之前添加名称冲突.

为了完善它,local变量是"动态"范围的,与my变量不同,因为它们也可以从同一块内调用的子程序访问.

  • +1 表示“如果不在‘{}’中,‘my’变量的词法作用域是在同一文件中的[...]”。这对我很有用,谢谢。 (2认同)

FMc*_*FMc 48

一个例子:

use strict;

for (1 .. 2){
    # Both variables are lexically scoped to the block.
    our ($o);  # Belongs to 'main' package.
    my  ($m);  # Does not belong to a package.

    # The variables differ with respect to newness.
    $o ++;
    $m ++;
    print __PACKAGE__, " >> o=$o m=$m\n";  # $m is always 1.

    # The package has changed, but we still have direct,
    # unqualified access to both variables, because the
    # lexical scope has not changed.
    package Fubb;
    print __PACKAGE__, " >> o=$o m=$m\n";
}

# The our() and my() variables differ with respect to privacy.
# We can still access the variable declared with our(), provided
# that we fully qualify its name, but the variable declared
# with my() is unavailable.
print __PACKAGE__, " >> main::o=$main::o\n";  # 2
print __PACKAGE__, " >> main::m=$main::m\n";  # Undefined.

# Attempts to access the variables directly won't compile.
# print __PACKAGE__, " >> o=$o\n";
# print __PACKAGE__, " >> m=$m\n";

# Variables declared with use vars() are like those declared
# with our(): belong to a package; not private; and not new.
# However, their scoping is package-based rather than lexical.
for (1 .. 9){
    use vars qw($uv);
    $uv ++;
}

# Even though we are outside the lexical scope where the
# use vars() variable was declared, we have direct access
# because the package has not changed.
print __PACKAGE__, " >> uv=$uv\n";

# And we can access it from another package.
package Bubb;
print __PACKAGE__, " >> main::uv=$main::uv\n";
Run Code Online (Sandbox Code Playgroud)

  • 好答案.遗憾的是,我不能不止一次地投票 (2认同)

dao*_*oad 12

应对范围界定是对Perl范围规则的一个很好的概述.它已经够老了,our在文本正文中没有讨论过.它在最后的注释部分中讨论.

本文讨论了包变量和动态范围,以及它与词法变量和词法范围的区别.


Óla*_*age 6

perldoc对 our 有一个很好的定义

与 my 不同,my 既为变量分配存储空间,又将一个简单名称与该存储空间关联起来以便在当前作用域内使用,而 our 则将一个简单名称与当前包中的包变量关联起来,以便在当前作用域内使用。换句话说,our 与 my 具有相同的作用域规则,但不一定创建变量。


ism*_*ail 6

my用于局部变量,其中我们用于全局变量.更多关于Perl中变量范围的阅读:基础知识.

  • 小心折腾本地和全球的话.适当的术语是词汇和包.您不能在Perl中创建真正的全局变量,但有些已经存在,如$ _,而local指的是具有本地化值(由本地创建)的包变量,而不是词汇变量(使用my创建). (14认同)

Xu *_*ing 5

我曾经在Perl中遇到过一些关于词汇声明的陷阱,这些陷阱使我感到困惑,这些陷阱也与此问题有关,因此我在这里添加摘要:

1.定义还是声明?

local $var = 42;
print "var: $var\n";
Run Code Online (Sandbox Code Playgroud)

输出为var: 42。但是,我们无法确定local $var = 42;是定义还是声明。但是呢:

use strict;
use warnings;

local $var = 42;
print "var: $var\n";
Run Code Online (Sandbox Code Playgroud)

第二个程序将引发错误:

Global symbol "$var" requires explicit package name.
Run Code Online (Sandbox Code Playgroud)

$var没有定义,这意味着local $var;只是一个声明!在local用于声明变量之前,请确保之前已将其定义为全局变量。

但是为什么这不会失败?

use strict;
use warnings;

local $a = 42;
print "var: $a\n";
Run Code Online (Sandbox Code Playgroud)

输出为:var: 42

这是因为$a和一样$b,也是Perl中预定义的全局变量。还记得排序功能吗?

2.词汇还是全局?

在开始使用Perl之前,我是一名C程序员,所以词法和全局变量的概念对我来说似乎很简单:它只对应于C中的自动变量和外部变量。但是有一些小的区别:

在C语言中,外部变量是在任何功能块外部定义的变量。另一方面,自动变量是在功能块内部定义的变量。像这样:

int global;

int main(void) {
    int local;
}
Run Code Online (Sandbox Code Playgroud)

在Perl中,事情很微妙:

sub main {
    $var = 42;
}

&main;

print "var: $var\n";
Run Code Online (Sandbox Code Playgroud)

输出为var: 42$var是全局变量,即使它是在功能块中定义的!实际上,在Perl中,默认情况下任何变量都声明为全局变量。

该课程始终是use strict; use warnings;在Perl程序的开头添加的,这将迫使程序员显式声明词法变量,这样我们就不会为理所当然的一些错误所迷惑。