2016-01-24 50 views
6

在Perl中,我一直很喜歡參數傳遞的鍵值對風格,子程序參數作爲鍵值對沒有臨時變量

fruit(apples => red);

我這個做了很多:

sub fruit { 
    my %args = @_; 
    $args{apples} 
} 

純粹爲了緊湊,不得不這樣做的方法不止一種,是有辦法之一:

  • 訪問鍵值對而不將@_分配給散列?即在一個單一的聲明?

  • 有子程序的參數自動成爲哈希引用,可能通過一個子程序原型?

無:

  • 分配到一個臨時變量my %args = @_;

  • 通過引用具有呼叫者通即fruit({ apples => red });純粹是爲了美學


試圖

  • ${%{\@_}}{apples}

    嘗試參照@_,解釋,作爲一個散列ref,將通過鍵訪問的值。

    但我得到一個錯誤,這不是一個散列引用。 (它是不是^。^)我想C,其中你可以投三分球,除其他事項外,避免明確再分配。

  • 我也試過子程序原型

    sub fruit (%) { ... }

    ...不過參數得到壓縮成@_如常。

+2

'%'原型與'@'原型相同。 '%'對讀者有額外的影響。 – ikegami

+1

如果將指向數組的指針轉換爲指向C中散列的指針,則在嘗試使用該指針時會發生段錯誤。 – ikegami

回答

6

不能執行散列查找(${...}{...}),而無需散列。但是你可以創建一個匿名散列。

my $apples = ${ { @_ } }{apples}; 
my $oranges = ${ { @_ } }{oranges}; 

你也可以使用簡單的提領後的語法

my $apples = { @_ }->{apples}; 
my $oranges = { @_ }->{oranges}; 

這將是非常低效的,但。你會創建每個參數一個新的哈希值。這就是爲什麼一個叫哈希正常使用。

my %args = @_; 
my $apples = $args{apples}; 
my $oranges = $args{oranges}; 

然而,另一種方法是使用散列片。

my ($apples, $oranges) = @{ { @_ } }{qw(apples oranges)}; 

以下是反引用後的版本,但它只是在5.24+ [1]可供選擇:

my ($apples, $oranges) = { @_ }->@{qw(apples oranges)}; 

  1. ,如果你使用的是可在5.20+如下:

    use feature qw(postderef); 
    no warnings qw(experimental::postderef); 
    
+2

[添加別人的答案給你自己做出更好的答案](http://meta.stackexchange.com/questions/35211/adding-someone-elses-answer-to-your-own-to-make-a-更好的答案) – cdlane

+0

@cdlane,從技術上講,我只是重新添加了原來在我的答案中的信息。 – ikegami

4

如果你更關心緊湊比效率,你可以這樣來做:

sub fruit { 
    print(+{@_}->{apples}, "\n"); 

    my $y = {@_}->{pears}; 

    print("$y\n"); 
} 

fruit(apples => 'red', pears => 'green'); 

原因+{@_}->{apples}使用的{@_}->{apples}反而是它與print BLOCK LIST語法print衝突沒有它(或其他一些消歧手段)。

+0

@ikegami非常有趣 - 我想補充一點,{@_} - > {apples}'也似乎與新塊的開始發生衝突,如果它位於沒有函數名前面的行上。反正它不會編譯。我從來不知道一元'+'操作符 - 好東西。 – iPherian

+1

@iPherian,一元'''字面上什麼都不做。它在運行時不存在;它甚至不會強制標量上下文。但是在這種情況下它很有用。需要消除歧義的常見地點是「地圖」的論點。 'map + {...},LIST'用於強制'map EXPR,LIST'語法,'map {; ...} LIST'用於強制執行map BLOCK LIST語法。 – ikegami