[Perl语法篇] 变量作用域:our、local、my、state

I.知识点概要:

    1.变量范围分为两类:全局、局部

    2.全局变量标准(our)关键字、局部变量标准(my)关键字

    3.(local)关键字将全局变量临时借用为局部、(state)关键字将局部变量变得持久


  在Perl中,所有的变量、子程序和其他可以被命名的实体默认都拥有包作用域(亦称“全局作用域”),也就是说它们存在于当前包的符号表中。

  如果没有关键字声明变量,Perl会默认变量为全局变量,但如果启用了use strict指令强制规定,则Perl会强制要求必须先声明变量后才可使用变量。

 1.包域全局our

 our操作符用于显式地创建包作用域变量。

 # 关键字our
  our $Scalar =1;                  #全局, 作用域为包
  sub Subroutine{
      our $Scalar =2;              #全局, 作用域为包
      $Scalar +=1;
      print $Scalar;                 
  }
  &Subroutine;                     #输出3
  &Subroutine;                     #输出3 
  print $Scalar;                   #输出3

  注1our操作符是在Perl 5时代被引入的,Perl 4时代变量均为全局,且不需声明。到了Perl 5时代为避免变量混乱,引入了use strict指令强制规定必须声明变量,而our操作符就是定义了一个看起来像词法作用域的全局变量,从而通过strict指令限制。

  注2:如果全局变量已存在,则our的作用是声明这个全局变量(类似于C中的extern)。

 2.临时全局local

   local操作符需配合our操作符使用(或其他包中的全局变量),用于产生一个局部变量的效果。

 # 关键字local
  our $Scalar =1;                  #全局, 作用域为包
  sub Subroutine{
      local $Scalar =2;            #临时全局变量,  作用域为子程序内部
      $Scalar +=1;
      print $Scalar;                 
  }
  &Subroutine;                     #输出3
  &Subroutine;                     #输出3 
  print $Scalar;                   #输出1 

  注1:很显然local只能声明已定义的全局变量,被my定义的变量是不可以被local声明的,即local本身不能创造变量。

  注2local变量是在运行时起作用,它会将参数的值保存在一个运行栈中,当执行线程离开所在作用域时,原先作用域暂存的变量会被恢复。

3.私有局部my

  虽然local操作符的历史比my操作符久远,但Perl后来还是新增了my来分担local的工作,在大部分情况下应首选my,但也有一些特殊情况下必须使用local。

  my操作符用于创建词法作用域变量,通过my创建的变量,存活于声明开始的地方,直到闭合作用域的结尾。

  闭合作用域指的可以是一对花括号中的区域,可以是一个文件,也可以是一个eval字符串。
 # 关键字my
  my $Scalar =1;                   #私有局部变量, 作用域为当前文件
  sub Subroutine{
      my $Scalar =2;               #私有局部变量, 作用域为花括号
      $Scalar +=1;
      print $Scalar;                 
  }
  &Subroutine;                     #输出3
  &Subroutine;                     #输出3 
  print $Scalar;                   #输出1

  注1my是编译时在私有符号表中创建新变量,这个变量在运行时无法使用名字进行独立访问,即它不存在于包符号表中(非全局)。

  注2:当闭合作用域里的my变量与外层变量重名时,当前my变量有效,当退出作用域时,外层变量值不变。


4.持久局部state

  state操作符功能类似于C里面的static修饰符,它与my不同的是,my变量在退出闭合作用域后其值不存在了,而state变量的值会被保留。

 # 关键字state
  my $Scalar =1;                   #私有局部变量, 作用域为当前文件
  sub Subroutine{
      state $Scalar =2;            #持久局部变量, 作用域为子程序内部
      $Scalar +=1;
      print $Scalar;                 
  }
  &Subroutine;                     #输出3
  &Subroutine;                     #输出4 
  print $Scalar;                   #输出1 

  注1state仅能创建闭合作用域为子程序内部的变量

  注2state是从Perl 5.10开始引入的,所以使用前必须加上use 5.010或更高版本指令。

  注3state可以声明标量、数组、哈希。但在声明数组和哈希时,不能对其初始化(至少Perl 5.14不支持)。

-------------------------------------------------------------------------------------------------------------------------------

 I.参考资料:

    [1]. 盛春译.《Perl语言入门》[第六版][M].东南大学出版社,2012.

           第四章,子程序

    [2]. 周良忠译.《C程序员精通Perl》[M].人民邮电出版社,2003.

           第7章,子程序和模块

    [3]. 盛春译.《Perl高效编程[第2版][M].人民邮电出版社,2011.

           第4章,子程



 II.修订记录:

    2013.01.08.  初稿

-------------------------------------------------------------------------------------------------------------------------------

### Perl 哈希表定义和基本操作 在 Perl 中,哈希(Hash)是一种以键值对(key-value pairs)形式存储数据的数据结构。每个键是唯一的,并且与一个值相关联。哈希非常适合用于需要通过唯一标识符快速查找、插入或删除数据的场景。 #### 定义哈希 可以使用多种方式来定义一个哈希。以下是一些常见的方法: ```perl # 使用胖箭头 => 操作符定义哈希 my %hash = ( "name" => "Alice", "age" => 30, "email" => "alice@example.com" ); # 或者使用普通括号定义哈希 my %hash2 = ("key1", "value1", "key2", "value2"); # 或者逐个赋值 my %hash3; $hash3{"fruit"} = "apple"; $hash3{"drink"} = "juice"; ``` #### 访问哈希元素 可以通过指定键来访问哈希中的值: ```perl print $hash{"name"}; # 输出: Alice ``` 如果请求的键不存在于哈希中,则返回 `undef`。为了避免警告信息,可以在使用前检查键是否存在。 #### 检查键是否存在 使用 `exists` 函数来判断某个键是否存在于哈希中: ```perl if (exists $hash{"age"}) { print "Key 'age' exists.\n"; } ``` #### 删除哈希元素 使用 `delete` 函数可以从哈希中删除特定的键值对: ```perl delete $hash{"email"}; ``` 执行此操作后,`email` 键将不再存在于哈希中。 #### 获取哈希的所有键和值 可以分别使用 `keys` 和 `values` 函数获取哈希的所有键和值: ```perl my @keys = keys %hash; my @values = values %hash; print "Keys: @keys\n"; # 输出所有键 print "Values: @values\n"; # 输出所有值 ``` 这些函数返回的是列表,因此可以直接用于循环或其他列表处理操作。 #### 遍历哈希 可以使用 `foreach` 循环遍历哈希的所有键,并访问对应的值: ```perl foreach my $key (keys %hash) { print "Key: $key, Value: $hash{$key}\n"; } ``` 这种方式允许你逐一处理哈希中的每个键值对。 #### 嵌套哈希 Perl 还支持嵌套哈希,即哈希的值本身也是一个哈希引用: ```perl my %nested_hash = ( user1 => { name => "Bob", role => "Admin" }, user2 => { name => "Charlie", role => "User" } ); print $nested_hash{user1}{name}; # 输出: Bob ``` 嵌套哈希在处理复杂数据结构时非常有用,例如配置文件解析或多维数据存储[^4]。 #### 哈希的灵活性 Perl 哈希的键可以是任意表达式的结果,只要其求值结果为字符串。例如: ```perl my $foo = 'bar'; print $family_name{$foo . 'ney'}; # 打印 'rubble' ``` 这种特性使得 Perl 哈希在动态构建键时非常灵活[^3]。 ---
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

痞子衡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值