Вернуть множественный массив из подпрограммы perl - PullRequest
1 голос
/ 22 марта 2019

Я даю четыре аргумента подпрограмме perl, используя их, подпрограмма создает два отдельных массива @temp_V и @temp_t.Когда я пытаюсь вернуть их в свою основную программу, я больше не получаю два отдельных массива.Вместо этого значения в @temp_t добавляются с @temp_V, давая мне один массив.

Как решить эту проблему?Вот мой код:

$Vmin=-5;
$Vmax=5;
$N_pulses=5;
$Freq=25e3;

my (@V, @t)=create_FORC($Vmin,$Vmax,$Freq,$N_pulses);

print "@V \n\n\n"; 
#print "@t \n"; 

sub create_FORC($Vmin,$Vmax,$Freq,$N_pulses)
{
my $Vmin=shift;
my $Vmax=shift;
my $Freq=shift;
my $N_pulses=shift;

my $rtime=1/(4*$Freq);
#print "$rtime \n";

undef @temp_V;
undef @temp_t;

push(my @temp_V,0);
push(my @temp_t,0);

push(@temp_V,$Vmin);

      for (my $pulse=0;$pulse<$N_pulses;$pulse++)
      {
      $V_peak=($Vmax-$Vmin)/$N_pulses*($pulse+1)+$Vmin;
      $del_t=($V_peak-$Vmin)*$rtime;  
          push(@temp_V,$V_peak); 
          push(@temp_V,$Vmin);  
          push(@temp_t,$del_t);
      } 
 push(@temp_V,0);

 print "@temp_V \n";
 print "@temp_t \n";

return (@temp_V, @temp_t); 

}

Ответы [ 3 ]

5 голосов
/ 22 марта 2019

Вы не можете. Когда вы возвращаете что-то из подпрограммы, Perl возвращает список. Нет информации о том, сколько элементов находится в массиве, прежде чем он выйдет из подпрограммы.

Списки плоские в Perl. Они не могут быть вложенными.

(1, 2, (3, 4), ((), 5, (6)), 7)

Это эквивалентно:

(1, 2, 3, 4, 5, 6, 7)
((1), (2), (3), (4), (5), (6), (7))

Если вы хотите вернуть два разных массива, вам нужно вернуть ссылки на них.

sub foo {
    my @bar = qw/a b c/;
    my @qrr = qw/1 2 3/;

    return \@bar, \@qrr;
}

my ($letters, $numbers) = foo();

Затем вы можете разыменовать их в переменные массива или получить к ним доступ напрямую.

См. perlreftut и perlref для получения дополнительной информации о ссылках.

3 голосов
/ 22 марта 2019

Возвращает ссылки на массивы:

return \@temp_v, \@temp_t

Вам необходимо разыменовать их при назначении реальным массивам:

my ($V_ref, $t_ref)=create_FORC($Vmin,$Vmax,$Freq,$N_pulses);

А затем используйте @$V_ref вместо @V (и аналогично для @$t_ref и @t).

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

2 голосов
/ 22 марта 2019

Массивы не могут быть переданы подпрограммам, только количество скаляров.

Массивы не могут быть возвращены подпрограммами, только количество скаляров.

Когда вы делаете

return ( @temp_V, @temp_t );

вы возвращаете содержимое обоих массивов, как если бы вы сделали

return ( $temp_V[0], $temp_V[1], ..., $temp_t[0], $temp_t[1], ... );

Perl не знает, сколько элементов назначить вызывающему @V и сколько назначить вызывающему @t, поэтому он назначает все на @V.

Решение состоит в том, чтобы возвращать ссылки на массивы (поскольку ссылки являются скалярами).

return ( \@temp_V, \@temp_t );

Тогда вызывающий абонент становится

my ($V, $t) = create_FORC($Vmin, $Vmax, $Freq, $N_pulses);

print "@$V\n\n@$t\n"; 
...