2012-05-23 3 views
22

Можно создать дубликат: How do pass one array and one string as arguments to a function?проход массива и скаляр к подпрограмме Perl

У меня есть функция, или подпрограмму, которая принимает в качестве первого параметра в виде массива, а второй параметр, как скаляр. Например,

sub calc { 
    my @array = $_[0]; 
    my $scalar = $_[1]; 
    print @array, $scalar; 
} 

Проблема заключается в том, что функция делает массив равен первому значению массива, переданного в, и скаляр быть вторым значением массива, переданного в. Когда я хочу, чтобы первый массив, чтобы быть всем массивом, мне не нужно делать глубокую копию массива. Например,

my @array = ('51', 'M'); 
my $scalar = 21; 

и

calc(@array, $scalar) 

напечатает 51 M, когда я хочу 51 M 21.

ответ

42

Вы должны передать его в качестве справки:

calc(\@array, $scalar)

А затем получить доступ к нему, как: my @array = @{$_[0]};

+3

Обратите внимание, что вторая часть моего ответа сделает копию массива. Вы также можете просто оставить его в качестве ссылки и получить доступ к нему по всей вашей функции. – happydave

+0

На самом деле это не работает, я попробовал. Вы проверили это? –

+0

Извините, я полагаю, что @ применяется до [0]. Я поставил фиксированную версию с фигурными скобками вокруг $ _ [0]. – happydave

2

Список аргументов в подпрограмме Perl представляет собой просто плоский массив. Если вы хотите передать отдельный массив, вы должны передать его как ссылку на массив.

8

Вы можете передать ссылку на массив вашей функции:

calc(\@array, $scalar); 

Когда вам нужно получить доступ к элементам @array в своей подпрограмме, вы можете сделать это следующим образом:

my $array = $_[0]; 

# access first element of array 
print $array->[0]; 

Редактировать: Поскольку это ссылка на исходный массив, любые изменения, сделанные в подпрограмме, будут отражаться в исходном массиве.

+2

Прохладный, я знал, что это была проблема синтаксиса, спасибо! –

+0

@Dan, Это была не синтаксическая ошибка. Проблема в том, что вы не понимали, что список аргументов подзаголовка оценивается как одно выражение, а не серия выражений, разделенных запятыми. – ikegami

+1

Ну, я так понял, поэтому я бы сказал, что не согласен. Я просто не знал, как сказать perl, что я прохожу через массив. –

9

Пройдите свой массив в подпрограмму известково как исй массив:

calc(\@array, $scalar); 

Затем в известково подпрограмме, то инициализировать входные параметры, как это:

sub calc { 
    my($array_ref, $scalar) = @_; 

    foreach my $item (@$array_ref) { 
    # process each item in the array ref 
    } 
} 
12

Либо использовать ссылку на массив в качестве первого аргумента или изменить аргументы таким образом, чтобы скаляр был первым, и массив появился после этого:

sub reversed_args 
{ 
    my($scalar, @array) = @_; 
    # ... 
    print @array, $scalar, "\n"; 
} 

my @array = ('51', 'M'); 
my $scalar = 21; 

reversed_args($scalar, @array); 

Не пытайтесь Perlprototypes (две статьи, одна на стеке   Переполнение, одна на PerlMonks).

+0

В чем заключается суть попытки не использовать прототипы? –

+0

Самая короткая форма: «Не использовать прототипы Perl»; следующая кратчайшая форма: «Прототипы функций Perl не работают так, как вы ожидаете, и эксперты рекомендуют вам не пытаться их использовать». Долгосрочная версия запускает что-то вроде «прототипов Perl - это неудачный эксперимент, который вызывает больше горя и ужаса, чем полезная помощь при их использовании, что приводит к затруднению диагностики проблем - по этому пути идут отчаяние и безумие». –

Смежные вопросы