Perl automatically initializes variables到undef
。
有没有办法覆盖这个默认行为并告诉Perl解释器将变量初始化为zero
(或其他一些固定值)?
答案 0 :(得分:13)
Code Complete中的建议对于C等语言很重要,因为当你有
时int f(void) {
int counter;
}
counter
的值是占用该记忆的任何事情。
在Perl中,使用
声明变量时my $counter;
毫无疑问$counter
的值是undef
而不是随机垃圾。
因此,建议背后的动机,即确保所有变量都以已知值开始,在Perl中自动满足,并且没有必要做任何事情。
你用计数器做的是增加或减少它们。结果:
my $counter;
# ...
++ $counter;
在Perl中得到了很好的定义。 $counter
将保留值1
。
最后,我认为,在大多数情况下,Perl中不需要计数器,并且可能需要重写广泛使用计数器变量的代码。
答案 1 :(得分:11)
据我所知,这是不可能的(而且不应该,它比$[
更危险。)
您可以按如下方式初始化变量以减少样板:
my ($x, $y, $z) = (0) x 3;
或将初始化移动到函数:
sub zero {$_ = 0 for @_}
zero my ($x, $y, $z);
甚至:
$_ = 0 for my ($x, $y, $z);
答案 2 :(得分:5)
没有。这样做可能会导致一些非常可怕且难以破译的错误,因此无论如何改变这样的行为并不是一个好主意。
在Perl中,您可以在第一次需要时正确声明变量,因此通常不需要先声明变量(使用或不使用初始化),然后再使用它们。此外,++
等运算符将使用未定义的值同样为零,因此您根本不需要初始化计数器:
# this is perfectly legal:
my $counter;
while ($some_loop)
{
$counter++;
}
但是,我可以通过提及您可以在Moose类中实现属性的自动初始化来插入Moose的插件:
package MyClass;
use strict;
use warnings;
use Moose;
has some_string => (
is => 'rw', isa => 'Str',
default => 'initial value',
);
has some_number => (
is => 'rw', isa => 'Int',
default => 0,
);
__PACKAGE__->meta->make_immutable;
1;
package main;
my $object = MyClass->new;
print "string has value: ", $object->some_string, "\n";
print "number has value: ", $object->some_number, "\n";
打印:
字符串有值:初始值
number有值:0
答案 3 :(得分:0)
你有一个具体的理由想要这样做,还是只是“因为代码完成说我应该”?
如果是前者,请分享原因,我们可以正确地讨论Perly实现真正目标的方法。
如果是后者,请记住 Code Complete 是一套用C语言编程的指南,而不是Perl。 Perl不是C并且有自己的优点和缺点,这也意味着它有一套不同的......我讨厌使用这个短语......最佳实践。适用于一种语言的指南不一定适用于另一种语言。 “在声明它们时总是初始化变量(如果可能的话)”在C中是一种合理的做法,但在Perl中通常是不必要的。
答案 4 :(得分:0)
为什么我不只是在第一次使用变量之前就简单地对其进行初始化?
答案:我留下很多“股票代码”。第一次使用时,整个“只是声明它”并不能真正适合我的生产风格。我可能会写“我的$ FirstVariable = 0;”的内容。包含在代码块的第一行中;然后在其后的上方插入一些内容,该内容也引用$ FirstVariable。现在,我通过移动代码块破坏了例程。
如果我在顶部声明所有需要的变量,那么不必担心因为必要的变量声明而重新排列代码块以杀死该过程。
此外,如果变量声明位于顶部,我可以轻松地注释掉一个声明,然后尝试运行例程。这对于解决大型复杂程序很方便,因为它将产生一个列表,其中包含行号,该列表将引用[现在未声明]变量的每个位置。当我看完所有内容后,只需删除注释字符即可恢复操作!