perl中對元素變量進行操作時,需要判斷其是否定義或是否為空或存在等操作,規(guī)范的操作要借助于defined、exist等函數(shù),那么它們之間有什么關(guān)系呢。
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的解釋來說就是: “這里什么也沒有,請繼續(xù)” 。它所表示的意思取決于其所處的上下文環(huán)境,如果這里的“什么也沒有”是一些“數(shù)字” ,則表現(xiàn)為 0。如果是“字符串”,則表現(xiàn)為空串。但undef既非數(shù)字也非字符串,它是另一種標量類型。
在使用新變量時,經(jīng)常不初始化,從而將變量作為0或者空串使用。許多操作當(dāng)參數(shù)不恰當(dāng)時返回undef。如果沒做特殊處理,通常會得到0或者空串。實踐中,這幾乎不會有什么問題。實際上,許多程序員利用這種性質(zhì)。但應(yīng)當(dāng)知道如果警告是打開的,那Perl在你不恰當(dāng)?shù)氖褂梦炊x值時會提醒你。例如,將一個undef的變量賦給另一個變量不會有什么問題,但如果print某個未定義的值則將引起警告。
另一個能返回 undef 的操作是行輸入操作:<STDIN>。通常它會返回文本中的一行。但如到了文件的結(jié)尾,則返回undef。要分辨其是undef還是空串,可以使用defined函數(shù),它將在為undef 時返回false,其余返回true。
當(dāng)undef作用于操作符環(huán)境時,表示將被操作的變量或函數(shù)進行"注銷"操作。
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;也就是判斷該變量是否是被賦過值的,其實這里當(dāng)一個變量被聲明之后通常他是沒有被賦值的,所以該函數(shù)就是用來完成這個工作的。未賦值的時候,他對外顯示的應(yīng)該是什么也沒有,這和給標量賦值空的時候?qū)ν怙@示一樣,但是本質(zhì)卻是完全不同的:賦值為空也是一種賦值,與未賦值是兩種不同的情況,即使對外顯示相同,但是defined卻能夠明白的知道兩者之間的不同,用defined來判斷一下標量就可以明白他是否是undef的了,若為undef則返回為0,若為非undef則返回1。下面舉一示例來說明下定義與賦值之間的區(qū)別:
my $word;#沒有賦值
if((defined $word)==0){print "0\n$word"}
else{print "1\n$word";}
結(jié)果為第一行為0
第二行為空,說明defined返回為0,那說明$word沒有賦值也就是undef的。
將my $word;改為my $word="";再運行一次。
結(jié)果為第一行為1
第二行為空,說明defined返回為非0,說明$word已經(jīng)被賦值了,且賦值為空,所以第二行顯示為空,雖然兩次的$word都為空,但是卻是一個沒有被賦值,一個已經(jīng)被賦值為空了。
exists
用于判斷hash、array(ref)中的元素是否存在,function函數(shù)是否定義。
判斷一個hash中的鍵是否存在,鍵存在但有可能是undef。在hash中,當(dāng)檢驗一個元素值是否被定義是用defined,當(dāng)檢驗一個key在hash中是否存在時,用exists(即使該鍵下的值不存在)。
print "Exists\n" if exists $hash{$key};
print "Defined\n" if defined $hash{$key};
print "True\n" if $hash{$key};
當(dāng)作用于數(shù)組時
print "Exists\n" if exists $array[$index];
print "Defined\n" if defined $array[$index];
print "True\n" if $array[$index];
作用于函數(shù)時
print "Exists\n" if exists &subroutine;
print "Defined\n" if defined &subroutine;
注意,子函數(shù)后不能帶()
exists ⊂ # OK
exists &sub(); # Error
下面是在函數(shù)中使用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';
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請
點擊舉報。