第三章 Perl語(yǔ)言(二)-值

變量值

新手程序員往往只關(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ù)組是容器瓣距。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市代咸,隨后出現(xiàn)的幾起案子蹈丸,更是在濱河造成了極大的恐慌,老刑警劉巖呐芥,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逻杖,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡思瘟,警方通過查閱死者的電腦和手機(jī)荸百,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來滨攻,“玉大人够话,你說我怎么就攤上這事≌÷颍” “怎么了更鲁?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)奇钞。 經(jīng)常有香客問我澡为,道長(zhǎng),這世上最難降的妖魔是什么景埃? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任媒至,我火速辦了婚禮,結(jié)果婚禮上谷徙,老公的妹妹穿的比我還像新娘拒啰。我一直安慰自己,他們只是感情好完慧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布谋旦。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪册着。 梳的紋絲不亂的頭發(fā)上拴孤,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音甲捏,去河邊找鬼演熟。 笑死,一個(gè)胖子當(dāng)著我的面吹牛司顿,可吹牛的內(nèi)容都是我干的芒粹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼大溜,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼化漆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起猎提,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤获三,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后锨苏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疙教,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年伞租,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了贞谓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡葵诈,死狀恐怖裸弦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情作喘,我是刑警寧澤理疙,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站泞坦,受9級(jí)特大地震影響窖贤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜贰锁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一赃梧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧豌熄,春花似錦授嘀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)览闰。三九已至,卻和暖如春巷折,著一層夾襖步出監(jiān)牢的瞬間焕济,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工盔几, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人掩幢。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓逊拍,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親际邻。 傳聞我的和親對(duì)象是個(gè)殘疾皇子芯丧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 第5章 引用類型(返回首頁(yè)) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,233評(píng)論 0 4
  • 從匹配中返回值 Match 對(duì)象 成功的匹配總是返回一個(gè) Match 對(duì)象, 這個(gè)對(duì)象通常也被放進(jìn) $/ 中, (...
    焉知非魚閱讀 1,800評(píng)論 0 1
  • 有心的朋友可能注意到了缨恒,一部日本的動(dòng)漫電影火遍了我們的生活,到處可以見到與它相關(guān)的東西轮听,比如朋友圈刷屏骗露、手機(jī)壁紙、...
    簡(jiǎn)意梵閱讀 354評(píng)論 2 3
  • 鄉(xiāng)村的夜晚 是上帝的施舍血巍,老天的饋贈(zèng) 久違了的父老鄉(xiāng)親 在這日漸臨近的端午佳節(jié) 窗外萧锉,日頭正毒 我失去了鄉(xiāng)土,自然...
    碧海青天2017閱讀 562評(píng)論 0 0
  • “不回去述寡?”歷川疑惑道柿隙。 徐中聽見聲音轉(zhuǎn)過身來。 “蹭車咯鲫凶≠餮拢”徐中朝他彎著嘴角。 “小鬼頭倒是挺會(huì)占便宜的螟炫〔ǜ剑”歷川...
    噠噠噠5678閱讀 342評(píng)論 0 0