2013-03-07 15 views
12

Specjalna tablica, @_, w której obecne są wszystkie argumenty przekazywane do funkcji, jest w rzeczywistości aliasem przekazywanych argumentów. W związku z tym wszelkie zmiany, które wprowadzimy bezpośrednio do tej specjalnej tablicy @_, będą również odzwierciedleniem w głównej. To jest jasne.Perl: Specjalna tablica @_ nie jest tak naprawdę pseudonimem?

#!/usr/bin/perl 

use warnings; 
use strict; 

$\="\n"; 

sub func { 
     print \@_; 
     $_++ for(@_); 
} 

my @arr=(2..4); 
print \@arr; 
func(@arr); 
print "@arr"; 

Dla powyższego programu, spodziewałem odniesienie @arr i @_ się wskazywać na tym samym miejscu, ponieważ jest aliasem. Ale tak nie jest.

na prowadzeniu powyższego:

ARRAY(0x1b644d0) 
ARRAY(0x1b644e0) 
3 4 5 

Jeśli są wskazując na 2 różnych miejscach, w jaki sposób zmiany wykonane w @_ odzwierciedla w @arr?

Czy widzę coś nie tak? Proszę o poradę.

+4

'@ _' nie jest aliasem do czegokolwiek. To nie jest to, co mówi dokumentacja. Poszczególne * elementy * '@ _' są aliasami. –

Odpowiedz

17

To może odpowiedzieć Ci pytanie:

use warnings; 
use strict; 

$\="\n"; 

sub func { 
     print \@_; 
     $_++ for(@_); 
     print \$_ for @_; 
} 

my @arr=(2..4); 
print \@arr; 
func(@arr); 
print "@arr"; 
print \$_ for @arr; 

Wyjście

ARRAY(0x17fcba0) 
ARRAY(0x1824288) 
SCALAR(0x17fcc48) 
SCALAR(0x18196f8) 
SCALAR(0x1819710) 
3 4 5 
SCALAR(0x17fcc48) 
SCALAR(0x18196f8) 
SCALAR(0x1819710) 

Jak widać, poszczególne argumenty mają ten sam adres, ale pojemnik nie jest taka sama. Jeśli przesuniesz element do @_ w func, @arr nie zmieni się (możesz zrobić shift w funct). Zatem każdy argument jest aliasem, a elementy tablicy są przekazywane jako pojedyncze elementy. @_ zawiera wszystkie elementy przekazane do podprogramu. Jeśli chcesz zmodyfikować argument tablicowy, musisz przekazać go przez odniesienie.

+2

Bardzo dziękuję za wiele rzeczy ... dziś dziękuję ... – Guru

11

@_ nie jest aliasem; jego elementami są.

Pamiętaj, że

func(@arr); 

jest taka sama jak

func($arr[0], $arr[1], ...); 

ponieważ jedyną rzeczą, która może być przekazana do sub jest lista skalarów i tablicą ocenia się na liście jego elementy w kontekście listy.

To znaczy

func(@arr); 

jest w zasadzie taka sama jak

local @_; 
alias $_[0] = $arr[0]; 
alias $_[1] = $arr[1]; 
... 
&func; 

Zmiana elementów @_ zmieni elementy @arr, ale dodawanie i usuwanie elementów @_ nie zmieni @arr od są to różne tablice.

>perl -E"@a=(4..6); sub { $_[0] = '!';  say @_; }->(@a); say @a;" 
!56 
!56 

>perl -E"@a=(4..6); sub { splice(@_,0,1,'!'); say @_; }->(@a); say @a;" 
!56 
456 
+0

dzięki ikegami .... – Guru

+0

Ulepszony przykład. – ikegami

Powiązane problemy