perl中my与our的区别介绍

先来看下our的用法。

require 5.006
当版本号小于 5.006 的时候,会返回失败,从而导致模块加载失败。
所以它的作用就是保证模块调用环境的 Perl 版本。

our 和 my 一样,都是对变量的声明,
不过 our 声明的是包全局变量,
而 my 声明的是词法变量。

不过,经过 our 声明的变量,它会变得像一个词法变量一样,
其实这也是 our 存在的目的:用来欺骗 strict pragma,使 strict 以为它是一个词法变量,其实却不是。

有一个简单的办法可以理解 our:
1,你就把 our 声明的变量和 my 声明的当成一样。
2,记住 our 和 my 的区别:our 声明的是一个包全局变量,因此在符号表中存储(可以通过全限定在任何地方访问),而 my 声明的是一个真正的词法变量,只能在闭合块中访问。
使用my的情况:

代码如下:

my $var = 1;
{
    my $var = 2;
    print $var, "\n";
}
print $var, "\n";

输出:
2
1

使用our的情况:

代码如下:

our $var = 1;
{
    our $var = 2;
    print $var, "\n";
}
print $var, "\n";

输出:
2
2

附:perl中our的用法

其实,our 的出现有它的历史,
Perl 和别的语言不同,可以随便声明变量,
在 Perl 4 那个时代,根本就不需要 my 什么的,
随便写个名字,就是变量了。
在 Perl 5 中仍然如此,除非你用 my 明确声明为词法变量,否则所有的变量都是(包)全局变量,而且可以不声明直接使用。
但是,这样有个坏处,那就是万一不小心写错名字了,或者解符号引用的时候,字符串运算错了,都会造成很多麻烦(因为按照 Perl 5 语法,这些都是正确的,其结果就是产生一个新的变量,很显然,这不是你想要的目的。)

所以,为了解决这些问题,在 Perl 5 中就引入了 strict 和 warnings 两个 pragma,它们的作用,就是限制变量不声明直接使用,
经过 strict 和 warnings 限制后,所有没有声明的直接使用的变量都会报错。但是 my 声明的变量又是局部变量,local 又不能创造变量,
所以,我们就没法使用全局变量了(注1),
因此就又引入了 our,our 的作用就是声明一个全局变量,但是让 strict 和 warnings 以为它是词法变量,因此 our 声明的变量也是词法作用域的。但是实际上它是全局变量。

注1:
如果不使用 our,我们有两种办法可以创建全局变量:
1,用 no strict "vars" 临时关掉 strict pragma,声明完了再用 use strict "vars" 打开。
2,用变量的全限定名称,如 $main::var 或者 $foo::bar 这样子。

use,package,our 三者之间无任何关系。

use 是加载一个 .pm 文件,
package 是切换当前名字空间,
our 是在当前名字空间中创建一个变量,如果该变量已经存在,则 our 只起到一个声明的作用。

你还是没有明白 our 和 my 的区别。
our (或者什么修饰都没有)声明的是“包全局变量”,它的是“依附”在“包”上面的,它的存储位置是“包符号表”,
my 声明的是“词法变量”,它是“依附”在“代码块”上的,它的存储位置是“代码块”的“变量标签薄”,所以词法变量不可以从代码块之外访问(除了传递引用)。
但是包全局变量就不同了,用全限定就可以访问。

(0)

相关推荐

  • Perl中chomp和chop的区别介绍

    chomp是用来删除换行符. 复制代码 代码如下: #!/usr/bin/perl $c="abcde"; chomp($c); print "$c\n"; [root@ak]# perl a.pl abcde chop是用来删除最后一个字符. 复制代码 代码如下: #!/usr/bin/perl $c="abcde"; chop($c); print "$c\n"; [root@ak]# perl a.pl abcd cho

  • perl中my与our的区别介绍

    先来看下our的用法. require 5.006当版本号小于 5.006 的时候,会返回失败,从而导致模块加载失败.所以它的作用就是保证模块调用环境的 Perl 版本. our 和 my 一样,都是对变量的声明,不过 our 声明的是包全局变量,而 my 声明的是词法变量. 不过,经过 our 声明的变量,它会变得像一个词法变量一样,其实这也是 our 存在的目的:用来欺骗 strict pragma,使 strict 以为它是一个词法变量,其实却不是. 有一个简单的办法可以理解 our:1,

  • iOS开发中class和#import的区别介绍

    在iOS开发过程中,我们在一些源码中经常会看到导包的时候有的用#import进行导包,但是有的的时候也会看到用@class进行导包,那么这两种方式有什么区别呢? 一 @class和#import的主要区别 首先说一下最主要的区别: •使用#import引入一个类的头文件,编译时会将该类的头文件中的所有信息都引入,包含属性和方法: •使用@class仅仅是告诉编译器这是一个类,并不会因入该类的其他信息,而我们所关心的也仅此一点,而不需要知道该类的内部有哪些属性和方法,因此使用@class可以提升编

  • python中if和elif的区别介绍

    多个if语句是每次单独判断 比如: 例子一 a = 5 if a < 6: #条件1 print(1) if a < 7: #条件2 print(2) else: print(3) 条件1和条件2是独立的,第一次判断a的值小于6,所以打印出数字1,第二次判断a的值小于7,所以打印出2.如果所有的if语句都判断失败,才会执行else后的语句,否则else语句不执行. 如果条件2修改为elif,结果就不同了 例子二 a = 5 if a < 6: #条件1 print(1) elif a &

  • tomcat自定义Web部署文件中docBase和workDir的区别介绍

    本文主要介绍的是tomcat自定义Web部署文件中docBase和workDir的区别,下面话不多说,直接来看详细介绍. 首先看这段tomcat配置文件: <Context path="/web" reloadable="false" docBase="D:\CAPRuntime\src\main\webapp" workDir="D:\CAPRuntime\src\main\webapp"/> 其中的docBas

  • perl中my和our的区别分析

    perl中our的用法require 5.006当版本号小于 5.006 的时候,会返回失败,从而导致模块加载失败.所以它的作用就是保证模块调用环境的 Perl 版本. our 和 my 一样,都是对变量的声明,不过 our 声明的是包全局变量,而 my 声明的是词法变量. 不过,经过 our 声明的变量,它会变得像一个词法变量一样,其实这也是 our 存在的目的:用来欺骗 strict pragma,使 strict 以为它是一个词法变量,其实却不是. 有一个简单的办法可以理解 our:1,你

  • ASP.NET Core中Razor页面与MVC区别介绍

    作为.NET Core 2.0发行版的一部分,还有一些ASP.NET的更新.其中之一是添加了一个新的Web框架来创建“页面”,而不需要复杂的ASP.NET MVC.新的Razor页面是一个比较简单的MVC框架版本,在某些方面是老的“.aspx” WebForms的演变. 在本文中,我们将介绍使用ASP.NET Razor页面和MVC的一些细节. Razor页面基础知识 ASP.NET MVVM vs MVC Razor页面的优点和缺点 使用Handlers实现多个GET.POST Action方

  • JavaScript中的null和undefined区别介绍

    JavaScript中存在2个代表信息不存在的特殊值:null和undefined.个人认为可以从以下角度来理解这两个特殊值之间的区别: 1.null代表有存储信息的容器(比如之前被赋过值的变量),但该容器中的内容为空. 2.undefined代表不存在用于存储信息的容器. JavaScript中的null与其它多数编程语言中的null没有什么区别,基本用于表示信息值为空:而在JavaScript中下述情况下表达式返回结果为undefined: 1.从未被赋过值的变量. 2.访问某个对象不存在的

  • TypeScript中let和var的区别介绍

    目录 1.作用域不同 2.let没有变量提升 3.let变量不能重复声明 4.for循环中的let与var 1.作用域不同 用var声明的变量,只有函数作用域和全局作用域,没有块级作用域.而let可以实现块级作用域,只能在代码块{}内有效,在{}之外不能访问,如下代码所示: { let a = 0; var b = 1; } console.log(a) // ReferenceError: a is not defined console.log(b) // 1 2.let没有变量提升 在代码

  • c#中 String和string的区别介绍

    不知道大家有没有发现,在c# string类型可以写成string和String,那么,它们有什么区别呢? string是c#中的类: String是Framework的类: C# string 映射为 Framework的 String. 如果用string,编译器会把它编译成String,所以如果直接用String就可以让编译器少做一点点工作. 也就是说 string是String的别名而已

随机推荐