2010-09-16 88 views
5

我有一個函數返回一個數組,我想只從該數組中獲取第一個項目而沒有爲該數組聲明一個變量。基本上,它應該是這樣的:如何從一個返回Perl數組的函數中獲得第一項?

functionReturningArray()[1]

除了不起作用。

我真的不想浪費空間來聲明整個數組,因爲我不需要它,我寧願不浪費額外的代碼行。無論如何要做到這一點在一行?

回答

12
my $item = (function_returning_list())[0]; 

函數不能返回數組,它們可以返回數組的內容(即列表)。列表索引從0開始,因此函數返回的第一項是(func)[0]。你也可以說

my ($item) = function_returning_list(); 

這使function_returning_list在列表環境和不分配(按順序)的左側端列表中的變量。

需要注意的是

sub function_returning_list { 
    return ("a", "b", "c") 
} 

my $item = function_returning_list(); 

可能不會做你期望什麼是重要的。 $item變量將被分配爲"c"。這是因爲在標量上下文中沒有這樣的事情。相反,您在標量上下文中具有逗號運算符,並且在void上下文中評估左側表達式,放棄結果,然後在標量上下文中評估右側。

我調用一個序列(而不是一個列表),並且如果像C樣式for循環的情況很有用。

+8

在標量上下文中沒有這樣的事情。在標量上下文中沒有這樣的事情。在標量上下文中沒有這樣的事情。在標量上下文中沒有這樣的事情。在標量上下文中沒有這樣的事情。在標量上下文中沒有這樣的事情。在標量上下文中沒有這樣的事情。在標量上下文中沒有這樣的事情。 – 2010-09-16 16:52:52

+2

您在標量上下文中有逗號運算符。參見[瞭解列表和數組之間的區別](http://www.effectiveperlprogramming.com/blog/39) – 2010-09-16 16:53:50

+0

@brian d foy這就是「這叫做序列(而不是列表)」的意思。標量上下文的概念是一個有用的謊言。向人們解釋要容易得多。特別是在'sub f {return @a} my $ x = f();'這樣的情況下,沒有逗號。 – 2010-09-16 16:59:10

2

首先,[1]是列表中的第二項,因爲Perl使用基於0的索引。

其次,你需要函數的返回值在列表上下文中進行評估,以便有一個列表來訪問。

(functionReturningArray())[0] 
2

比Chas的回答更進一步Chas的回答中,沒有列表期間這樣的事情。

與填充此角色的元組類型的Python不同,Perl的列表完全是編譯器/解釋器中堆棧的構造。這就是爲什麼你不能參考一個列表。

就像python使用元組一樣,當使用如=賦值運算符這樣的構造時,perl會自動推送和移動堆棧以移動變量組。 (因爲=的綁定比,更緊密,Perl的優先規則是需要括號的。 Perl和Python機制之間的宏觀層次差異是上下文在整個表達式中傳播。

因此,當在標量上下文中,該上下文分配給每個運算符,並且運算符在無效上下文中執行它的左側,然後在標量上下文中執行它的右側,然後返回它。但是在列表上下文中,,運算符將其參數壓入堆棧,所有這些都在列表上下文中執行。然後堆棧被傳遞給賦值運算符,然後移入左值。堆棧/列表本身對於Perl級別代碼是不可改變的,它的修改工具實際上是Perl的所有語法。

因此,儘管在標量上下文中引用列表是不正確的(因爲這種事情不可能發生),但您可以引用列表的行爲,如語法結構(由,運算符構造,由數組切片或列表片)。在標量上下文中,類似結構的列表的行爲是返回列表的最後一個元素。如何實現這一點取決於表達式中的運營商。這當然與標量上下文中返回它們長度的數組的行爲形成對比。

爲了用一個例子闡明並最終服從規則和實際回答這個問題:

假設my @array = (10, 11, 12);

  • 標量上下文

    my $val = (10, 11, 12);  # $val is 12 
    my $val = (10 .. 20)[0 .. 5]; # $val is 15  
    my $val = @array;    # $val is 3 
    my $val = function();   # $val is the last executed expression 
    
    • 所以如果function10, 11, 12結束那麼價值將是12
    • 如果代替是@array則該值將是3
    • 和如果它與10, 11, 12, @array結束值也是3

  • 列表上下文

    my ($val) = (10, 11, 12);  # $val is 10 
    my ($val) = (10 .. 20)[0 .. 5]; # $val is 10 
    my ($val) = @array;    # $val is 10 
    my ($val) = function();   # $val is the first executed expression 
               # in the last statement. 
    
    • 所以如果function10, 11, 12結尾,則值wil升是10
    • 如果代替是@array則該值將是10
    • 和如果它與10, 11, 12, @array結束值也是10

  • 和完整性,列表上下文斂整個列表到一個數組

    my @val = (10, 11, 12);  # @val is 10, 11, 12 
    my @val = (10 .. 20)[0 .. 5]; # @val is 10, 11, 12, 13, 14, 15 
    my @val = @array;    # @val is 10, 11, 12 
    my @val = function();   # @val is the the last executed statement 
    
    • 所以如果function10, 11, 12然後@val結束將是10,11,12
    • 如果代替是@array然後@val將是10,11,12
    • 和如果它與10, 11, 12, @array結束然後@val將是10,11,12,10 ,11,12
+1

不要混淆語言與其實現。 – 2010-09-17 07:39:13

+0

我不明白如何指出Perl中的「列表」是如何混淆的,它並不像是有其他的實現......我寫的東西有什麼不對嗎? – 2010-09-17 08:23:00

相關問題