分享

defined exist函数:Perl

 公彦栋 2017-12-06
perl中对元素变量进行操作时,需要判断其是否定义或是否为空或存在等操作,规范的操作要借助于defined、exist等函数,那么它们之间有什么关系呢。

undef

undef EXPR

Undefines the value of EXPR, which must be an lvalue. Use only on a scalar value, an array (using @ ), a hash (using % ), a subroutine (using & ), or a typeglob (using * ). Saying undef $hash{$key} will probably not do what you expect on most predefined variables or DBM list values, so don't do that; see delete. Always returns the undefined value. You can omit the EXPR, in which case nothing is undefined, but you still get an undefined value that you could, for instance, return from a subroutine, assign to a variable, or pass as a parameter.

变量在第一次赋值前有一个特殊值undef,按照Perl的解释来说就是: “这里什么也没有,请继续” 。它所表示的意思取决于其所处的上下文环境,如果这里的“什么也没有”是一些“数字” ,则表现为 0。如果是“字符串”,则表现为空串。但undef既非数字也非字符串,它是另一种标量类型。

在使用新变量时,经常不初始化,从而将变量作为0或者空串使用。许多操作当参数不恰当时返回undef。如果没做特殊处理,通常会得到0或者空串。实践中,这几乎不会有什么问题。实际上,许多程序员利用这种性质。但应当知道如果警告是打开的,那Perl在你不恰当的使用未定义值时会提醒你。例如,将一个undef的变量赋给另一个变量不会有什么问题,但如果print某个未定义的值则将引起警告。

另一个能返回 undef 的操作是行输入操作:<STDIN>。通常它会返回文本中的一行。但如到了文件的结尾,则返回undef。要分辨其是undef还是空串,可以使用defined函数,它将在为undef 时返回false,其余返回true。

当undef作用于操作符环境时,表示将被操作的变量或函数进行"注销"操作。
undef *xyz; # destroys $xyz, @xyz, %xyz, &xyz, etc.
my %h=(
a=>1,b=>2,c=>3
);

#undef $h{'b'};       
#delete $h{'b'};

foreach (keys %h){
 say $_.':'.$h{$_};
}

defined

defined EXPR

Returns a Boolean value telling whether EXPR has a value other than the undefined value undef. If EXPR is not present, $_ is checked.

defined用来判断一个变量是不是undef,也就是知道有这个变量但不知道它是不是undef;也就是判断该变量是否是被赋过值的,其实这里当一个变量被声明之后通常他是没有被赋值的,所以该函数就是用来完成这个工作的。未赋值的时候,他对外显示的应该是什么也没有,这和给标量赋值空的时候对外显示一样,但是本质却是完全不同的:赋值为空也是一种赋值,与未赋值是两种不同的情况,即使对外显示相同,但是defined却能够明白的知道两者之间的不同,用defined来判断一下标量就可以明白他是否是undef的了,若为undef则返回为0,若为非undef则返回1。下面举一示例来说明下定义与赋值之间的区别:
my $word;#没有赋值
if((defined $word)==0){print "0\n$word"}
else{print "1\n$word";}

结果为第一行为0
第二行为空,说明defined返回为0,那说明$word没有赋值也就是undef的。

将my $word;改为my $word="";再运行一次。

结果为第一行为1
第二行为空,说明defined返回为非0,说明$word已经被赋值了,且赋值为空,所以第二行显示为空,虽然两次的$word都为空,但是却是一个没有被赋值,一个已经被赋值为空了。

exists

用于判断hash、array(ref)中的元素是否存在,function函数是否定义。

判断一个hash中的键是否存在,键存在但有可能是undef。在hash中,当检验一个元素值是否被定义是用defined,当检验一个key在hash中是否存在时,用exists(即使该键下的值不存在)。

print "Exists\n"    if exists $hash{$key};
print "Defined\n"   if defined $hash{$key};
print "True\n"      if $hash{$key};

当作用于数组时
print "Exists\n"    if exists $array[$index];
print "Defined\n"   if defined $array[$index];
print "True\n"      if $array[$index];
        
作用于函数时
print "Exists\n"  if exists &subroutine;
print "Defined\n" if defined &subroutine;

注意,子函数后不能带()
exists &sub;    # OK
exists &sub();  # Error

下面是在函数中使用defined,undef操作的示例
The correct function is defined. undef undefines $optional:
sub Freeoa {
 my($length, $optional) = @_;
 if(! defined $optional) {
  # Do whatever needs to be done if $optional isn't defined.
 }
 else{
 # Do whatever can be done if $optional *is* defined.
 }
}

Another way to deal with it (especially Perl 5.10+) is to use the "defined or" operator, //, like this:
sub Freeoa{
 my $length = shift;
 my $optional = shift // 'Default Value';
 # Do your stuff here.
}

What that does is detect whether the return value of shift @_ is defined. Since you already called shift once, we're now testing the second parameter. If it's defined, assign the value to $optional. If it's not defined, assign 'Default Value' to $optional. Of course you have to come up with your own sane default.

如果使用的版本早于5.10,通常的写法为:
my $optional = shift;
$optional = defined $optional ? $optional : 'Default value';

...or...

my $length = shift;
my $optional = defined( $_[0] ) ? shift : 'Default value';

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多