2011-01-26 56 views
0
1 @backwards = reverse qw(yabba dabba doo); 
2 $backwards = reverse qw(yabba dabba doo); 
3 
4 print @backwards; #gives doodabbayabba 
5 print $backwards."\n"; #gives oodabbadabbay 
6 print @backwards."\n"; #gives 3 

在上面的代碼中爲什麼line 6給出3作爲輸出?如果它與\ n連接,爲什麼它會轉換爲標量上下文?Perl中的標量和列表上下文

由於

回答

7

你的問題最終是「爲什麼是在第6行標量上下文@backwards」,其中 引發了一個問題,「我怎樣才能確定一個術語的上下文?」。

上下文由下式確定「什麼是圍繞」(即它的「上下文」)的術語。

如何確定術語的上下文?通過查看 正在使用該術語的運算符/函數。

如果你 沒有有用的stackoverflow夥伴來告訴你它的上下文,你可以按照什麼步驟來找出@ backwards的上下文?

在這裏,我們有

print @backwards."\n" 

所以有兩個運營商/功能。我們如何知道哪一個將背景 提供給@ backwards?通過諮詢優先。近perlop.pod的頂部,我們有Perl的 優先級表(打印是一個「列表操作符」):

left terms and list operators (leftward) 
... 
left + - . 
... 
nonassoc list operators (rightward) 

哦,太好了,現在我們需要知道相片是否是向左或向右。通過諮詢 在perlop中的「條款和列表操作符(左側)」部分( 優先級列表之後)我們看到,打印是向右這裏,因爲我們還沒有括號括 它的參數。

所以串聯是更高的優先級,所以級聯提供上下文@backwards。

下一步是檢查文檔(再次perlop中),用於連接:

Binary "." concatenates two strings. 

字符串是標量,所以二進制 「」連接兩個標量。

,我們終於擁有它!

@backwards具有標量上下文因爲級聯提供標量上下文 其每個操作數。

嗚。這很簡單,不是嗎:-)

8

6行給出3因爲.操作者施加在其兩個操作數的標量上下文,@backwards在標量上下文產生3(因爲在標量上下文任何陣列報告在它的元素的數量)。

嘗試:

print "@backwards\n"; 

要加入在數組中的元素,可以使用join

print join(', ', @backwards) . "\n"; 
+5

保持列表上下文會'印刷@backwards,「\ n」` – 2011-01-26 09:17:19

+0

感謝您的回答的另一個選擇。 – Prakhar 2011-01-26 12:07:56

4

語境是棘手的。有時幾個像素可以使所有的差異。考慮以下兩條線:

print localtime, "\n"; 
print localtime. "\n"; 

您是否發現了區別?

這兩個陳述看起來非常相似。但是,這兩起案件發生的情況完全不同。

在第一個語句中,print傳遞了一個參數列表。 print的文檔說明它在它的參數上施加了列表上下文。因此,對本地時間的調用在列表上下文中進行評估,並且該函數返回一個數字列表。

在第二個語句中,print接收一個參數。該參數是通過將調用本地時間的結果與換行符相結合而創建的字符串。連接運算符在其兩個操作數上施加標量上下文。因此,對localtime的調用以可讀的字符串格式返回當前時間。然後將該字符串與換行連接,並將結果字符串傳遞給打印機。打印調用仍然在列表上下文中評估其參數,但該上下文對單個字符串參數的解釋方式沒有影響。

對於另一個類似的問題,請看Perl中上下文的更多角落,請參閱我前兩天在博客上發佈的the question。我會在幾天內發佈解決方案。

+0

謝謝你的解釋。 – Prakhar 2011-01-26 12:08:15