在Perl中,如何简单地检查是否定义了$变量并包含非零长度的字符串?

Jes*_*ica 76 string perl

我目前使用以下Perl来检查变量是否已定义并包含文本.我必须首先检查defined以避免"未初始化的值"警告:

if (defined $name && length $name > 0) {
    # do something with $name
}
Run Code Online (Sandbox Code Playgroud)

写这个有更好的(可能是更简洁的)方法吗?

bri*_*foy 73

您经常会看到对定义性的检查,因此您不必处理使用undef值的警告(在Perl 5.10中它会告诉您有问题的变量):

 Use of uninitialized value $name in ...
Run Code Online (Sandbox Code Playgroud)

因此,为了解决这个警告,人们会提出各种代码,而且代码开始看起来像是解决方案的重要部分,而不是泡泡糖和胶带.有时候,最好通过明确地关闭您要避免的警告来显示您正在做的事情:

 {
 no warnings 'uninitialized';

 if( length $name ) {
      ...
      }
 }
Run Code Online (Sandbox Code Playgroud)

在其他情况下,使用某种空值而不是数据.使用Perl 5.10的defined-or运算符,您可以给出length一个显式空字符串(已定义,并返回零长度),而不是将触发警告的变量:

 use 5.010;

 if( length( $name // '' ) ) {
      ...
      }
Run Code Online (Sandbox Code Playgroud)

在Perl 5.12中,它更容易一些,因为length在未定义的值上也返回undefined.这可能看起来有点愚蠢,但这让我想成为的数学家高兴.这不会发出警告,这就是这个问题存在的原因.

use 5.012;
use warnings;

my $name;

if( length $name ) { # no warning
    ...
    }
Run Code Online (Sandbox Code Playgroud)

  • 此外,在v5.12及更高版本中,`length undef`返回undef,而不是警告并返回0.在布尔上下文中,undef与0一样假,所以如果你的目标是v5.12或更高版本,你可以写`if(length $ name){...}` (3认同)

Ada*_*ire 23

正如mobrule所指出的那样,您可以使用以下内容代替小额节省:

if (defined $name && $name ne '') {
    # do something with $name
}
Run Code Online (Sandbox Code Playgroud)

你可以抛弃定义的支票并获得更短的东西,例如:

if ($name ne '') {
    # do something with $name
}
Run Code Online (Sandbox Code Playgroud)

但是在$name未定义的情况下,虽然逻辑流程将按预期工作,但如果您正在使用warnings(并且您应该使用),那么您将得到以下警告:

Use of uninitialized value in string ne

因此,如果有$name可能无法定义,您确实需要首先检查定义,以避免该警告.正如SinanÜnür指出的那样,您可以使用Scalar :: MoreUtils通过以下方法获得开箱即用的代码(检查定义,然后检查零长度)empty():

use Scalar::MoreUtils qw(empty);
if(not empty($name)) {
    # do something with $name 
}
Run Code Online (Sandbox Code Playgroud)


Sin*_*nür 16

首先,因为length总是返回一个非负数,

if ( length $name )
Run Code Online (Sandbox Code Playgroud)

if ( length $name > 0 )
Run Code Online (Sandbox Code Playgroud)

是等价的.

如果您可以使用空字符串替换未定义的值,则可以使用Perl 5.10的//=运算符将RHS分配给LHS,除非定​​义了LHS:

#!/usr/bin/perl

use feature qw( say );
use strict; use warnings;

my $name;

say 'nonempty' if length($name //= '');
say "'$name'";
Run Code Online (Sandbox Code Playgroud)

请注意,没有关于未初始化变量的警告,$name如果未定义则为空字符串.

但是,如果您不想依赖于安装5.10,请使用Scalar :: MoreUtils提供的功能.例如,以上内容可以写成:

#!/usr/bin/perl

use strict; use warnings;

use Scalar::MoreUtils qw( define );

my $name;

print "nonempty\n" if length($name = define $name);
print "'$name'\n";
Run Code Online (Sandbox Code Playgroud)

如果你不想破坏$name,请使用default.

  • 在这种情况下我不会使用// =因为它会将数据更改为副作用.相反,使用稍短的`length($ name //'')`. (4认同)

Gau*_*rav 6

如果我不关心变量是否undef等于'',我通常总结为:

$name = "" unless defined $name;
if($name ne '') {
  # do something with $name
}
Run Code Online (Sandbox Code Playgroud)