【无标题】对Perl中defined、undef、exist的理解

对Perl中defined、undef、exist的理解

创建时间2014-06-29 11:22:23 作者阿炯

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都为空,但是却是一个没有被赋值,一个已经被赋值为空了。

 

 

undef表示的像是数据库中的Null。它表示空,什么也没有,是完全未定义的。这不等于字符串的空,不等于数值0,它是另一种类型。

 

在某些时候,perl程序本该报错的时候(如使用未赋值的变量,参数越界,读取文件时到了文件结尾eof),perl实际上不会报错,而是返回undef。但如果开启了warnings功能,则这种类型的问题,某些情况下会给出warning信息,而不是返回undef。多数情况下,将其当作空或0就好了,因为在需要数值的时候,undef代表的就是0,需要字符串的时候,undef就是空字符串。所以perl中的完全可以直接使用未定义的变量,因为未定义的变量起始就是undef。它可以被当作0,也可被当作空字符串。

 

例如,下面两个语句中,$sum和$str都是未定义的,初始时它们分别表示数值0和空字串''。

$sum += $i;

$str .= "abc";

 

可以直接将undef关键字赋值给某个变量,表示这个变量是undef的,这可以取消一个变量的定义。相当于bash shell中的unset。

$line=undef;

 

如果想要判断这个undef确实是undef而不是字符串的空,可以使用defined()函数。如果是undef,则该函数返回false,否则返回true。

 

示例如下:

use v5.20;

 

my ($i,$str,$sum);

$sum += $i;

$str .= "freeoa";

 

#undef($str);

#$sum=undef;

 

defined($str) ? say 'Valid' : say 'Invalid';

 

say 'Sum:'.$sum ;

say 'Str:'.$str;

 

 

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';

 

 

 

参考文档

undef

 

defined

 

exists

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值