Perl中state输出1-5、my输出11111的原因及state作用说明
Perl 子程序内state与my变量的输出差异原因
两种声明方式输出结果不同,核心差异是变量的生命周期和初始化时机:
- 用
my声明时:my创建的是绑定单次子程序调用周期的词法局部变量。每次进入Counter子程序,都会重新生成一个全新的$i变量,将其赋值为0,再自增为1打印;子程序执行结束后,这个$i会被直接回收销毁。5次调用每次都走一遍「新建变量→初始化0→自增为1→销毁」的流程,所以连续输出5个1。 - 用
state声明时:state创建的是持久化词法变量,初始化逻辑只会在子程序第一次被调用时执行一次,子程序退出后变量不会被销毁,存储的值会被保留。第一次调用时$i初始化为0,自增到1打印;第二次调用直接复用上次留存的$i=1,自增到2打印,后续调用依次累加,最终就会依次输出1到5。
state关键字的通用作用规则
- 作用域规则和
my完全一致:变量仅在声明所在的词法作用域(子程序、代码块)内可访问,不会污染全局命名空间,外部代码无法直接读取或修改。 - 初始化仅执行一次:代码流第一次运行到state声明语句时才会执行赋值初始化,后续再经过该语句时,会直接复用已存在的变量实例,不会重复重置值。
- 生命周期贯穿程序运行全程:只要变量所属的词法作用域(比如示例中的Counter子程序)没有被销毁,变量存储的值就会一直留存,不会因为退出代码块/子程序就被回收重置。
- 版本要求:Perl 5.10及以上版本才原生支持state关键字,使用时需要提前通过
use feature 'state';开启特性,或直接声明use v5.10;及更高版本号自动启用。
示例代码对比
state版本(输出1-5)
use v5.10; sub Counter{ state $i = 0; $i++; print "$i\n"; } for (1..5){ Counter(); }
my版本(输出5个1)
sub Counter{ my $i = 0; $i++; print "$i\n"; } for (1..5){ Counter(); }
补充:state不仅可以用在子程序中,普通代码块里也可以使用,效果一致:比如在for循环块内声明state变量,同样只会初始化一次,循环过程中会保留累加的值。
内容的提问来源于stack exchange,提问作者grotivanhelden
相关产品推荐
相关产品推荐

