如何检查 Perl 标量变量是不是已初始化?

Posted

技术标签:

【中文标题】如何检查 Perl 标量变量是不是已初始化?【英文标题】:How do I check if a Perl scalar variable has been initialized?如何检查 Perl 标量变量是否已初始化? 【发布时间】:2010-09-17 20:35:00 【问题描述】:

以下是检查标量变量是否在 Perl 中使用 defined 初始化的最佳方法吗?

my $var;

if (cond) 
    $var = "string1";


# Is this the correct way?
if (defined $var) 
    ...

【问题讨论】:

你想解决什么问题? 检查undef 是查看变量是否已初始化的最佳方法;但是,如果在初始化后的任何时间将变量设置为 undef,这将使您的初始化测试失败,如下所述。 【参考方案1】:

Perl 不提供检查变量是否已初始化的方法。

但是,未使用某个值显式初始化的标量变量在默认情况下碰巧具有undef 的值。你是对的,defined 是检查变量是否具有 undef 值的正确方法。

还有其他几种方法。如果您想将变量分配给undef,您的示例代码似乎表明了这一点,例如,您可以使用 perl 的定义或运算符:

$var //= 'a default value';

【讨论】:

////= 运算符是在 Perl 5.10 中引入的。对于以前的版本,||||= 运算符执行相同的操作,只是它们会覆盖已初始化的“已定义但为假”值,例如 "0""" 请原谅,但标量默认为undef,而defined 运算符是Perl 提供的用于检查该值而不会引发“使用未初始化的变量”警告。 (因为你们都有-wuse strict 有效,对吧?) Blrfl:没错。那是你的意思吗?一个值为 undef 的标量与它是否已初始化完全无关,考虑到 perl 根本无法区分未初始化的标量和恰好持有值 undef 的标量,因为有人将它设置为 undef Blrfl: 标量 变量 是 undef,除非你给它们赋值,但这并不意味着如果你给它们赋值,它们就不是 undef。 @rafl 和 BDF:我想我的观点是,如果您正在编写的代码积极避免在引发警告的情况下使用未定义的标量,那么声明该标量而不初始化它们的语义就变成了 Perl为您将其初始化为undef。它可能会让人毛骨悚然,但我认为分配 undef 可以有效地取消初始化变量,因为它的行为与 Perl 为您完成的行为变得无法区分。 (希望这是有道理的......)【参考方案2】:

这取决于你想要做什么。正确的C 做事方式是在声明变量时对其进行初始化;但是,Perl is not C,因此您可能想要以下其中一项:

  1)   $var = "foo" unless defined $var;      # set default after the fact
  2)   $var = defined $var? $var : ...;     # ternary operation
  3)   ... if !(defined $var);              # another way to write 1)
  4)   $var = $var || "foo";                  # set to $var unless it's falsy, in which case set to 'foo'
  5)   $var ||= "foo";                        # retain value of $var unless it's falsy, in which case set to 'foo' (same as previous line)
  6)   $var = $var // "foo";                  # set to $var unless it's undefined, in which case set to 'foo'
  7)   $var //= "foo";                        # 5.10+ ; retain value of $var unless it's undefined, in which case set to 'foo' (same as previous line)

C 做事方式(不推荐):

# initialize the variable to a default value during declaration
#   then test against that value when you want to see if it's been changed
my $var = "foo";
...
if ($var eq "foo")
   ... # do something
 else 
   ... # do something else

另一种冗长的方法是在变量更改时创建一个类和一个标志,这是不必要的。

【讨论】:

【参考方案3】:

如果你不在乎它是否为空,它就是。否则你可以检查

if ( length( $str || '' )) 

【讨论】:

【参考方案4】:

这取决于你打算对变量做什么,不管它是否被定义;从 Perl 5.10 开始,您可以这样做(来自 perl51000delta):

一个新的操作符 // (defined-or) 已经实现。以下表达式:

 $a // $b

仅仅等同于

defined $a ? $a : $b

和声明

$c //= $d;

现在可以用来代替

$c = $d unless defined $c;

【讨论】:

【参考方案5】:

'defined' 如果变量有实值,则返回 true。

顺便说一句,在哈希中,这可能是真的:

if(exists $h$e && !defined $h$e)

【讨论】:

undef 是一个真实值。将其用作“没有价值”的指标虽然很常见,但只是一种约定。 “真实值”,如有效标量或参考值。 perl 中不存在无效的缩放器。 是的。你说的是严格的,我说的是常规的。 +1 因为我在徘徊到底发生了什么:$IniFile = "$ARGV[0]" ; # perl 定义或操作符 # 不起作用 perl -v (v5.12.3) $IniFile //= "$ProductVersionDir/conf/$HostName/ini/run-$EnvironmentName.$HostName.ini"; #工作! $IniFile = "/tmp/boo.ini" if ("$ARGV[0]" eq "" ) ;

以上是关于如何检查 Perl 标量变量是不是已初始化?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查“lateinit”变量是不是已初始化?

JavaScript 检查变量是不是存在(已定义/初始化)

JavaScript 检查变量是不是存在(已定义/初始化)

Perl如何检查数组是不是仍然为空?

如何检查 `let` 变量是不是已在 ES6 上声明?

如何检查“lateinit”变量是否已初始化?