Perl提供了一個調用的子程序的原型,使您可以編寫獲取類似內建函數的方式解析用戶潛艇系統。你想模擬的內建函數是map
,grep
或sort
,它們每個都可以將一個塊作爲它們的第一個參數。
要做到這一點與原型,使用sub name (&) {...}
其中&
告訴Perl的第一個參數的函數或者是塊(有或沒有sub
)或文字子程序\&mysub
。 (&)
原型指定了一個且只有一個參數,如果需要在代碼塊之後傳遞多個參數,則可以將其寫爲(&@)
,這意味着代碼塊後跟一個列表。
sub higher_order_fn (&@) {
my $code = \&{shift @_}; # ensure we have something like CODE
for (@_) {
$code->($_);
}
}
該子程序將在傳入列表的每個元素上運行傳入的塊。 \&{shift @_}
看起來有點神祕,但它所做的是移出列表的第一個元素,它應該是一個代碼塊。 &{...}
將該值解引用爲子例程(調用任何重載),然後\
立即引用它。如果該值是一個CODE ref,那麼它將被返回不變。如果它是一個重載的對象,它會變成代碼。如果它不能被強制轉換成CODE,則會引發錯誤。
要調用這個子程序,你可以這樣寫:
higher_order_fn {$_ * 2} 1, 2, 3;
# or
higher_order_fn(sub {$_ * 2}, 1, 2, 3);
的(&@)
的原型,可以讓你寫的參數作爲map
/grep
像塊使用高階函數的功能時纔會起作用。如果你使用它作爲一種方法,你應該省略原型,並用這種方式寫下來:
sub higher_order_method {
my $self = shift;
my $code = \&{shift @_};
...
$code->() for @_;
}
...
$obj->higher_order_method(sub {...}, 'some', 'more', 'args', 'here');
一般來說,函數原型是沒有必要的,我覺得它們有點用處。 – jiggy 2011-05-23 18:43:54
@jiggy請你詳細說一下嗎? – 2011-05-23 21:01:58
=>在這種情況下,使用'($)'原型可能並不意味着你的想法。它的意思是「給我一個論點」,但它也意味着「對這個論點強加標量上下文」。所以,如果你有一個數組中有一個元素,並且調用'foo_1 @ array',那麼'foo_1'將被傳遞數字'1',這是數組中元素的個數。要實際獲得第一個參數,您需要將其稱爲'foo_1 $ array [0]'。如果你沒有原型,那麼你可以稱它爲'foo_1 @ array',它可以正常工作。 – 2011-05-23 21:31:47