變量值
新手程序員往往只關(guān)注自己的程序要做些什么,而成熟的程序員則是在想如何為程序設(shè)計(jì)一個(gè)合適的數(shù)據(jù)模型够颠。****變量幫你對(duì)數(shù)據(jù)進(jìn)行抽象格侯,變量的值就是讓程序變得具體從而發(fā)揮實(shí)際作用格仲。****變量的值可以是你期望的任何東西,比如名字殴俱、地址政冻、家和學(xué)校的距離枚抵、你去年的花費(fèi)。在程序中明场,對(duì)數(shù)據(jù)的格式要求往往非常嚴(yán)格汽摹。程序員需要有效的方法(簡(jiǎn)單,快速苦锨,高效)來表示他們的數(shù)據(jù)逼泣。
字符串
字符串就是一連串的字符(可以是文本也可以說是二進(jìn)制數(shù)據(jù))。比如它可以是你的名字舟舒,也可以是一個(gè)圖片文件的內(nèi)容拉庶,或者程序本身源代碼。
在程序中秃励,要表示一個(gè)字符串時(shí)氏仗,你需要將它們包圍起來,最常見的就是使用單引號(hào)或雙引號(hào)將它們包圍起來:
my $name = 'Donner Odinson, Bringer of Despair';
my $address = "Room 539, Bilskirnir, Valhalla";
單引號(hào)包圍的字符表示的意思就是****字面本身****夺鲜,雙引號(hào)包圍的字符則****還可能具有非字面本身的意義(內(nèi)插/轉(zhuǎn)義)****皆尔。
單引號(hào)的使用有2個(gè)例外:要表示單引號(hào)自身時(shí)需要在前面加反斜杠;要表現(xiàn)反斜杠時(shí)也需要在前面加反斜杠:
'Don\'t forget to escape' #Don't forget to escape
'Modern \\ Perl' #Modern \ Perl
'backslash, not a quote: \\' #backslash, not a quote:\
雙引號(hào)包圍的字符則擁有更強(qiáng)的魔法币励,如支持更多反斜杠轉(zhuǎn)義:
"\t"
"\n"
"\f"
"\b"
它們分別表示制表慷蠕、換行、換頁(yè)食呻、退格流炕。
當(dāng)然對(duì)于雙引號(hào)包圍的普通字符意思不會(huì)變,僅僅表示這些是字符串字面本身仅胞。
如果要連接字符串每辟,可以使用點(diǎn)號(hào)操作符(.):
my $kitten = 'Choco' . ' ' . 'Spidermonkey';
my $kitten = "Choco" . " " . "Spidermonkey";
你也可以在雙引號(hào)中放入變量,那么變量的當(dāng)前內(nèi)容就會(huì)成為字符串的一部分干旧,就好像把他們連接在一起:
my $factoid = "$name lives at $address!";
my $factoid = $name . ' lives at ' . $address . '!';
如果要表示雙引號(hào)本身要在前面加反斜杠轉(zhuǎn)義:
my $quote = "\"Ouch,\", he cried. \"That hurt!\""; #"Ouch,", he cried. "That hurt!"
上面這個(gè)例子反斜杠有點(diǎn)多影兽,看起來亂糟糟的。所以Perl里還提供了操作符(q)和操作符(qq)來讓這種情況變得簡(jiǎn)單莱革。
q 操作符的效果就像單引號(hào),不會(huì)內(nèi)插讹开;qq操作符類似雙引號(hào)盅视,會(huì)內(nèi)插。
它們都需要定界符旦万。定界符可以是2個(gè)相同的符號(hào)闹击,也可以是成對(duì)的符號(hào)。
挑選合適的定界符可以避免上面例子中的反斜杠:
my $quote = qq{"Ouch", he said. "That hurt!"};
my $reminder = q^Don't escape the single quote!^;
my $complaint = q{It's too early to be awake.};
當(dāng)你需要聲明一個(gè)復(fù)雜的字符串時(shí)成艘,可以是用heredoc語(yǔ)法:
my $blurb =<<'END_BLURB';
He looked up. "Change is the constant on which they all
can agree. We instead, born out of time, remain perfect
and perfectly self-aware. We only suffer change as we
pursue it. It is against our nature. We rebel against
that change. Shall we consider them greater for it?"
END_BLURB
這里<<'END_BLURB'
語(yǔ)法有3部分赏半。二個(gè)小于號(hào)標(biāo)志著這里是heredoc語(yǔ)法贺归。用單引號(hào)引起表示這段字符串不做內(nèi)插(類似單引號(hào)的行為,且無例外--單引號(hào)反斜杠都原樣保留)断箫。如果沒有使用單引號(hào)引起默認(rèn)就是雙引號(hào)的行為(支持內(nèi)插)拂酣。END_BLURB就是結(jié)束定界符。****注意結(jié)尾定界符必須要在那一行的行首仲义!****
sub some_function {
my $ingredients =<<'END_INGREDIENTS';
Two eggs
One cup flour
Two ounces butter
One-quarter teaspoon salt
One cup milk
One drop vanilla
Season to taste
END_INGREDIENTS
}
Unicode和字符串
Unicode是一個(gè)用來表示世界上所有文字的字符系統(tǒng)婶熬。相對(duì)的就是純英文字符,英文字符集只有127個(gè)字符埃撵,只需要8個(gè)比特位就夠用了赵颅。這2種類型字符集都被廣泛使用,Perl的字符串對(duì)2種類型都支持暂刘。
Unicode字符序列
每一個(gè)字符都有一個(gè)碼點(diǎn)饺谬,這是該字符在Unicode字符集當(dāng)中的唯一標(biāo)識(shí)。
Octet序列(八位序列)
通常說的2進(jìn)制數(shù)據(jù)就是8位序列谣拣,一個(gè)8比特位的數(shù)字募寨,可以表示0到255。
為什么叫Octet序列而不是叫字節(jié)芝发?不同的計(jì)算機(jī)對(duì)字節(jié)的定義不一樣绪商,而Octet則總是表示8個(gè)比特位。
****Perl默認(rèn)將所有的輸入數(shù)據(jù)都視為八位序列辅鲸。****
字符編碼
****文件句柄中使用Unicode編碼****
如果你知道該以什么樣的編碼方式處理文件格郁,那就可以在IO層進(jìn)行指定,Perl會(huì)自動(dòng)做相應(yīng)的轉(zhuǎn)換独悴。如以UTF-8的編碼方式讀取文件:
open my $fh, '<:utf8', $textfile;
my $unicode_string = <$fh>;
對(duì)于已經(jīng)打開了的文件句柄例书,則可以使用binmode方法:
binmode $fh, ':utf8';
my $unicode_string = <$fh>;
binmode STDOUT, ':utf8';
say $unicode_string;
想要方便的在所有地方都啟用UTF-8,可以試試utf8::all模塊刻炒。
****在數(shù)據(jù)中使用Unicode編碼****
系統(tǒng)模塊Encode提供了各種各樣的編碼轉(zhuǎn)換功能决采。
my $from_utf8 = decode('utf8', $data); #對(duì)$data進(jìn)行UTF-8解碼
my $to_latin1 = encode('iso-8859-1', $string); #對(duì)$string進(jìn)行拉丁解碼
讀取的數(shù)據(jù)時(shí)進(jìn)行正確的解碼,輸出數(shù)據(jù)時(shí)進(jìn)行正確的編碼坟奥,能避免所有編碼方面的問題树瞭。
****在源代碼中使用Unicode編碼****
啟用utf8后就可以在代碼中使用UTF-8字符了:
use utf8;
sub £_to_¥ { ... }
my $yen = £_to_¥('1000£');
這樣寫代碼的前提條件是你的編輯器支持UTF-8,并且能將代碼文件以正確的編碼方式保存爱谁。
在雙引號(hào)包圍的字符串中晒喷,你可以使用\x{}語(yǔ)法來表示Unicode字符:
my $escaped_thorn = "\x{00FE}";
有些Unicode字符是有名字的,啟用charnames后访敌,可以使用\N{}語(yǔ)法用名字來表示:
use charnames ':full';
my $escaped_thorn = "\x{00FE}";
my $named_thorn = "\N{LATIN SMALL LETTER THORN}";
****隱式轉(zhuǎn)換****
當(dāng)你將多種字符集混合使用并且沒有指明時(shí)凉敲,Perl會(huì)自動(dòng)對(duì)字符串進(jìn)行編碼轉(zhuǎn)換,這有可能導(dǎo)致出現(xiàn)非常隱秘的問題,所以不要這樣做爷抓!
如果你的工作內(nèi)容是處理Unicode势决,請(qǐng)使用Perl 5.16以上的版本,并且總是遵循這樣一個(gè)原則:讀取的數(shù)據(jù)時(shí)進(jìn)行正確的解碼蓝撇,輸出數(shù)據(jù)時(shí)進(jìn)行正確的編碼果复。
關(guān)于Perl與Unicode的更多細(xì)節(jié)請(qǐng)閱讀:http://www.perl.com/pub/2012/04/perlunicook-standard-preamble.html
數(shù)字
Perl支持整型數(shù)字和浮點(diǎn)數(shù)字,你可以使用不同的方式來表示它們唉地,二進(jìn)制据悔、八進(jìn)制、十進(jìn)制耘沼、十六進(jìn)制:
my $integer = 42; #整型
my $float = 0.007; #浮點(diǎn)型
my $sci_float = 1.02e14; #科學(xué)計(jì)數(shù)法极颓,浮點(diǎn)數(shù)
my $binary = 0b101010; #二進(jìn)制0b前綴
my $octal = 052; #十六進(jìn)制0前綴
my $hex = 0x20; #十六進(jìn)制0x前綴
還可以使用下劃線來增加可讀性:(注意不是逗號(hào),因?yàn)槎禾?hào)在Perl中有特殊意義)
my $billion = 1000000000;
my $billion = 1_000_000_000;
my $billion = 10_0_00_00_0_0_0;
罕見的情況下你可能會(huì)有數(shù)字和字符相互轉(zhuǎn)換的困擾群嗤,這時(shí)可以看看系統(tǒng)模塊Scalar::Util( looks_like_number函數(shù))菠隆。
如果你需要識(shí)別數(shù)字類型(如整型數(shù)字、浮點(diǎn)型數(shù)字)狂秘,可以試試Regexp::Common模塊(CPAN)骇径。
Undef
Perl里的undef表示一個(gè)未分配、不確定者春、未知的值破衔。
一個(gè)聲明了但是沒有定義的標(biāo)量值就是undef:
my $name = undef; # unnecessary assignment
my $rank; # also contains undef
在布爾語(yǔ)境中,undef等效于假值钱烟。在字符串語(yǔ)境中內(nèi)插undef值的變量將會(huì)產(chǎn)生一個(gè)警告:
my $undefined;
my $defined = $undefined . '... and so forth';
#Use of uninitialized value $undefined in concatenation (.) or string...
使用defined來測(cè)試undef值將返回假晰筛;測(cè)試undef外的其他任何值都返回真。
my $status = 'suffering from a cold';
say defined $status; # 1, which is a true value
say defined undef; # empty string; a false value
空列表
在賦值右邊拴袭,使用一對(duì)小括號(hào)就表示一個(gè)空列表读第。
在標(biāo)量語(yǔ)境中,空列表等價(jià)于undef拥刻;在列表語(yǔ)境中怜瞒,就是一個(gè)空的列表。
當(dāng)在賦值左邊時(shí)般哼,()強(qiáng)制為列表語(yǔ)境:
my $count = () = get_clown_hats();
首先空列表強(qiáng)制為列表語(yǔ)境吴汪,所以會(huì)在列表語(yǔ)境中調(diào)用get_clown_hats(),函數(shù)會(huì)返回一系列的值(列表)蒸眠。然后賦值給空列表浇坐,空列表會(huì)將所有的值都丟棄,列表賦值這個(gè)操作又是在標(biāo)量上下文黔宛,所以結(jié)果就會(huì)將返回元素的個(gè)數(shù)。現(xiàn)在看起來可能有點(diǎn)繞,但隨著Perl技能的提高臀晃,你會(huì)越來越覺得自然觉渴。
列表
一個(gè)用逗號(hào)分隔的單個(gè)或多個(gè)表達(dá)式組就是一個(gè)列表。
可以作為值來使用:
my @first_fibs = (1, 1, 2, 3, 5, 8, 13, 21);
也可以用于被賦值:
my ($package, $filename, $line) = caller();
作為表達(dá)式列表:
say name(), ' => ', age();
****注意:列表不是由圓括號(hào)創(chuàng)建的徽惋,是由逗號(hào)創(chuàng)建的案淋。****
使用范圍操作符(..)可以很方便的創(chuàng)建列表:
my @chars = 'a' .. 'z';
my @count = 13 .. 27;
可以使用qw()操作符分隔空白來產(chǎn)生字符串列表:
my @stooges = qw( Larry Curly Moe Shemp Joey Kenny );
在qw()操作符中如果存在注釋符號(hào)和逗號(hào)會(huì)產(chǎn)生警告,因?yàn)檫@種情況極有可能是你不小心寫錯(cuò)了险绘。
列表和數(shù)組相似踢京,但他們不能互換。列表是值宦棺,而數(shù)組是容器瓣距。