簡體   English   中英

Perl將參數傳遞給子例程不起作用

[英]Perl Passing arguments to subroutine not working

我試圖將參數傳遞給perl子例程,無論出於何種原因,該子例程中的參數都為空。

...
...
...
print "Passing arguments $a, $b, $c, $d \n";
beforeEnd($a, %b, $c, $d);

sub beforeEnd() {
    my ($a, %b, $c, $d) = @_;
    print "a is $a, b is $b, c is $c, d is $d \n";
}

打印語句的輸出使我知道出了點問題。 奇怪的部分? 前兩個參數正確傳遞。

> Passing arguments 1, (1,2,3), 2, 3
> a is 1, b is (1,2,3), c is , d is

任何幫助將不勝感激。

因為當您將參數傳入或傳出子例程時,所有哈希和數組都會被粉碎平整。

您正在分配給%b ,它將吞噬所有參數。

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

sub test1 {
    my ( $first, @rest, $last ) = @_;

    print Dumper \@rest;

    print "First = $first, last = $last, rest = @rest\n";
}

sub test2 { 
   my ( $first, $second ) = @_;
   print "@$first ; @$second"; 
}

test1 ( 1, 2, 3, 4 ); 
test2 ( [1,2], [ 3,4] );

my @list1 = ( 1,2,3,4 );
my @list2 = ( 5,6,7,8 );

test1 ( @list1, @list2 );
test2 ( \@list1, \@list2 );

如果要保持數組或哈希完整無缺,則需要通過引用或作為最后一個參數傳遞它們。

如果在此處啟用strict警告,您也可能會得到warnings -這是強烈建議使用的原因之一-因為$b%b不相同。 您還會收到有關奇數作業的警告:

Odd number of elements in hash assignment at line 5.
Use of uninitialized value $b in print

當參數傳遞給Perl子例程時,它們被展平為@_表示的單個List。 從概念上講,這意味着如果您不傳遞對數組或哈希的引用,則會“丟失”某些數據。 “丟失”並不完全正確,因為所有數據仍然存在。 它只是不在您期望的變量中。 例如:

sub f {
   my (@a, @b) = @_;

   say 'a: ' . join(', ', @a);
   say 'b: ' . join(', ', @b);
}
f( qw(1 2 3), qw(a b c) );

您將獲得以下輸出:

a: 1, 2, 3, a, b, c
b: 

發生這種情況是因為第一個數組@a消耗了@_所有值,並且沒有@b存儲在@b 您的beforeEnd子例程中的哈希發生了相同的事情。 $c$d的值存儲在%b 作為一個例子,因為如果您通過了,我看不到變量值

beforeEnd(1, ( a => 1, b => 2 ), 'c', 3);

在您的子目錄中,您得到的是這樣的:

$a = 1
%b = ( a => 1, b => 2, c => 3 )
$c = undef
$d = undef 

您可以通過傳遞對哈希%b的引用來解決此問題:

beforeEnd($a, \%b, $c, $d);

子例程接受標量列表作為參數。 如果傳遞數組或哈希,則將傳遞數組或哈希的內容。 那意味着

f($a, %b, $c, $d)

是相同的

f($a, $b_key_1, $b_val_1, $b_key_2, $b_val_2, $b_key_3, $b_val_3, $c, $d);

@_應將多少個標量分配給%b Perl保持簡單,並分配所有剩余的標量,因此

my ($a, %b, $c, $d) = @_;

真的沒有什么不同

my $a = $_[0];        # The first argument
my %b = @_[1..$#_];   # All but the first argument
my $c;
my $d;

最好是傳遞對哈希的引用。 這樣可以避免問題,並且效率更高。

use Data::Dumper qw( Dumper );

sub beforeEnd {
    my ($a, $b, $c, $d) = @_;
    local $Data::Dumper::Terse = 1;
    print "a is $a, b is ".Dumper($b).", c is $c, d is $d \n";
}

beforeEnd($a, \%b, $c, $d);

關於您的代碼的離題注釋:

  • 您有一個原型,指示沒有期望的參數() ,但您希望有四個。 讓自己擺脫那個原型。

  • 您應該避免將$a$b用作變量,因為它可能會與sort

這些參數只能作為標量變量列表在子例程中傳遞。

每當將參數傳遞給子例程時,我們都需要傳遞哈希(或數組,對象)的引用。 ……打印“傳遞參數$ a,$ b,$ c,$ d \\ n”; beforeEnd($ a,\\%b,$ c,$ d);

sub beforeEnd() {
    my ($a, $b, $c, $d) = @_;
    print "a is $a, b is %$b, c is $c, d is $d \n";
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM