2012-02-16 75 views
12

在標量上下文中的列表賦值返回右手邊的元素個數:列表賦值

scalar(my ($hello, $there, $world) = (7,8)); #evaluates to 2 

爲什麼它評估的右手邊,併產生2,而不是新定義列表正在評估並返回3?

對我來說,它看起來像$hello得到7,$there得到8,並$world得到undef,則該列表中的標量上下文中計算,這將導致3,因爲這是在列表中的元素的數量($hello $there $world )。這似乎不可思議,我認爲上下文影響返回該評估表達式的一部分:

my $greeting = (($hello, $there, $world) = (7,8)); #2 

my @greeting = (($hello, $there, $world) = (7,8)); 
my $greeting_length = @greeting; #3 
+1

事實上,沒有:如果左側列表是標量環境的東西,價值將是'undef'。一個列表不是一個數組。 – darch 2012-02-17 00:32:12

+0

@darch,這沒有任何意義。 '($ hello,$ there,$ world)'(和'(7,8)')不能在'($ hello,$ there,$ world)=(7,8)'的標量上下文中執行。列表分配可能會返回3,如果它想,但沒有理由。 – ikegami 2012-02-17 05:11:17

+0

我的回答正是「那麼[列表($ hello,$ there,$ world)]在標量上下文中進行評估」。評估我的($ h,$ t,$ w)=(7,8,undef);標量($ h,$ t,$ w)'並且看到列表不是數組。 – darch 2012-02-17 20:06:42

回答

14

它的記錄數右邊的perlop(最後一句中的賦值運算符節)的元素:

同樣,列表上下文中的列表分配會生成分配給的左值列表,標量上下文中的列表分配會返回由該賦值右側的表達式生成的元素數量。

它的工作原理是,之所以是這樣,你可以這樣寫:

while (my ($key, $value) = each %hash) { ... } 

如果算的上分配的左側元素的數量,這將是一個無限循環。

如果您仔細考慮,左側的元素數量與右側相同,或者它是常量(當您分配給標量列表時)。在第一種情況下,你計算哪一方面沒有區別,在第二種情況下,計算右邊是更有用的。

另一方面,在列表上下文中,賦值操作符返回左手列表,因爲這更有用。如果您在修改列表元素的上下文中使用它,則需要修改剛分配給的變量。

回覆:您的評論在你的榜樣,(7,8)是兩個元素的列表,這就是爲什麼賦值運算符當您指定一個較短的列表,標量的長列表返回2,右手邊是不是在分配發生之前用「undef」填充「填充」。相反,從右側列表中沒有與它們關聯的值的變量將重置爲其默認值。對於標量變量,這是undef。對於數組,這是一個空數組。對於散列,這是一個空的散列。

+0

你的回答是有道理的,我明白它爲什麼這樣工作,但我更關心它是如何工作的。看到我對ikegamis post的評論。 – Brian 2012-02-16 20:27:11

+0

@Brian,在列表上下文中,您會得到左側列表,但在標量上下文中,您將獲得右側列表的計數。在這兩種情況下,這是因爲這是返回最有用的東西。有關詳細信息,請參閱我的更新回答 – cjm 2012-02-16 21:20:52

+0

@Brian,Perl中有許多函數和運算符,它們在標量上下文中返回的元素數量與它們在列表上下文中返回的元素數量不同。您必須閱讀文檔以瞭解功能或操作員將返回的內容。 – cjm 2012-02-16 21:23:57

6
似乎怪我哪邊是評估這方面的影響:

事實並非如此。評估列表賦值操作符的兩端(操作數),以及列表賦值是在標量上下文還是列表上下文中計算,不影響操作數的評估。

是否在標量上下文或列表上下文中評估列表分配隻影響它返回的值。

我以前創建Mini-Tutorial: Scalar vs List Assignment Operator,它試圖弄清楚這兩個賦值操作符,以及它們如何在標量和列表環境行爲之間的區別。

+0

我編輯那句話澄清了一下:'這似乎不可思議,我認爲上下文影響返回該評估表達式的一部分:'我知道這種情況下不影響評價,只返回結果,但我想知道怎麼運行的。如果賦值的右側被賦值並分配到左側,那麼標量爲什麼會變爲2?右側評估爲3個元素列表,然後將其分配給標量。這就像perl只是決定忽略優先規則並選擇表達式的哪一部分應該返回。 – Brian 2012-02-16 20:21:52

+0

除非,當然,我的'= @greeting(($你好,$有,$世界)=(7,8))'會給'@'greeting'(7,8)',而不是'($你好, $ there,$ world)',現在這對我來說會更有意義。但是如果'@ greeting'獲得'($ hello,$ there,$ world)'和'$ greeting'獲得'(7,8)'的結果,那麼這是沒有意義的。 – Brian 2012-02-16 20:42:01

+0

'$ greeting'不會得到'(7,8)'的結果。事實上,這是不可能的'$ greeting'得到這樣的結果'(7,8)',因爲這個'(7,8)'計算結果爲單值和列表值不能被分配到一個標量。 「@ greeting」和「$ greeting」都得到列表賦值的結果,這是「LHS評估的值列表」或「RHS評估的元素數量」,取決於上下文。你似乎暗示,如果返回不同的東西而不給出任何理由,如何讓其他結果有用,會更好。 – ikegami 2012-02-16 21:32:39