ajw*_*ood 2 variables perl initialization declaration
以下两个Perl变量声明之间有什么区别?
my $foo = 'bar' if 0;
my $baz;
$baz = 'qux' if 0;
Run Code Online (Sandbox Code Playgroud)
当它们出现在循环的顶部时,差异很大.例如:
use warnings;
use strict;
foreach my $n (0,1){
my $foo = 'bar' if 0;
print defined $foo ? "defined\n" : "undefined\n";
$foo = 'bar';
print defined $foo ? "defined\n" : "undefined\n";
}
print "==\n";
foreach my $m (0,1){
my $baz;
$baz = 'qux' if 0;
print defined $baz ? "defined\n" : "undefined\n";
$baz = 'qux';
print defined $baz ? "defined\n" : "undefined\n";
}
Run Code Online (Sandbox Code Playgroud)
结果是
undefined
defined
defined
defined
==
undefined
defined
undefined
defined
Run Code Online (Sandbox Code Playgroud)
似乎if 0失败了,所以foo永远不会重新初始化undef.在这种情况下,它是如何首先声明的?
ike*_*ami 12
首先,请注意my $foo = 'bar' if 0;记录为未定义的行为,这意味着它可以执行任何操作,包括崩溃.但我会解释无论如何会发生什么.
my $x 有三个记录的效果:
简而言之,它假设像Java一样Scalar x = new Scalar();,除非它在表达式中使用时返回变量.
但如果它实际上以这种方式工作,以下将创建100个变量:
for (1..100) {
my $x = rand();
print "$x\n";
}
Run Code Online (Sandbox Code Playgroud)
这意味着每个循环迭代只需要两次或三次内存分配my!非常昂贵的前景.相反,Perl只创建一个变量并在范围的末尾清除它.所以实际上,my $x实际上做了以下事情:
因此,只创建了一个变量[2].这比每次输入范围时创建一个CPU效率更高.
现在考虑如果你my有条件地执行或者根本不执行会发生什么.通过这样做,您将阻止它放置指令以清除堆栈上的变量,因此变量永远不会丢失其值.显然,这并不意味着发生,因此这my ... if ...;是不允许的原因.
有些人利用如下实施:
sub foo {
my $state if 0;
$state = 5 if !defined($state);
print "$state\n";
++$state;
}
foo(); # 5
foo(); # 6
foo(); # 7
Run Code Online (Sandbox Code Playgroud)
但这样做需要忽略禁止它的文档.以上可以安全地使用
{
my $state = 5;
sub foo {
print "$state\n";
++$state;
}
}
Run Code Online (Sandbox Code Playgroud)
要么
use feature qw( state ); # Or: use 5.010;
sub foo {
state $state = 5;
print "$state\n";
++$state;
}
Run Code Online (Sandbox Code Playgroud)
笔记:
"变量"可能意味着一些事情.我不确定这里的定义是否准确,但无关紧要.
如果除了子本身之外的任何内容都包含对变量的引用(REFCNT> 1)或者变量包含对象,则该指令将该变量替换为新的变量(在作用域出口上),而不是清除现有变量.这允许以下工作:
my @a;
for (...) {
my $x = ...;
push @a, \$x;
}
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
310 次 |
| 最近记录: |