2014-03-25 4 views
2

나는이 S.O를 우연히 만났을 때 스칼라로 배열 (또는리스트)을 전달하는 방법에 관한 글을 찾고 있었다. 게시물 ... Passing By Value - S.O.참조로 배열을 전달하는 예제는 Perl에서 어떻게 작동합니까?

선택한 답변 솔루션이 작동하는 것으로 나타 났지만 Perl을 배우려고 시도한 이후로 어떻게 작동하는지 알고 싶습니다. 이 줄에서

저자는 하위 프로그램에 전달 된 입력 매개 변수를 스칼라 변수에 배치하고 있습니다. 그런 다음이 행에서

@{$inArray} 

그는 "참조를 배열로 사용"한다고 말했습니다. 이 사실이 의미하는 바는 무엇이며 정확히 두 번째 줄에서 무엇이 진행되고 있습니까? 나는 그런 연산자를 결합하여 보지 못했습니다.

답변

5

먼저 염두에 두어야 할 것은 arrays and lists are not the same입니다.

참조는 다른 것 (배열, 해시, 다른 스칼라 등)의 메모리 주소를 보유하는 스칼라입니다. 멋진 포인터입니다. 펄

서브 루틴은 인수 목록을 (그리고 결과 목록을 반환합니다.)이 공통의 걸림돌 당신이

mysub(@foo, @bar) 

같은 것을하고 싶어하고 당신이 실현 때 @foo의 요소 @bar은 서브 루틴의 단일 목록으로 병합되었습니다. @foo의 크기를 미리 알고 있다면 목록의 시작 부분에서 적절한 수의 요소를 가져올 수 있지만 대개는 그렇지 않습니다.

참조는 스칼라이기 때문에이 문제를 해결할 수 있습니다. @foo@bar에 대한 참조를 전달하면 참조 배열의 크기에 관계없이 서브 루틴에 항상 처리 할 두 개의 매개 변수가 있음을 알 수 있습니다.

하지만 여전히 해당 배열의 데이터를 가져와야합니다. 그렇게하기 위해서, 우리는 Perl에게 참조가 가리키는 것을 얻도록 지시해야한다. 이를 역 참조라고합니다.

  1. 는 전체 배열을 얻을 my $elem = $ref->[42]을 사용하는 배열의 요소를 얻으려면 my @array = @$ref;
  2. 사용하려면 : 펄에서

    , 배열 참조 역 참조에 대한 일반적인 두 가지 방법이 있습니다.

첫 번째 예제는 때때로 @{ $ref }으로 작성되어 있지만 일부 중첩 구조를 명확하게해야 할 필요가없는 경우 추가 curlies는 필요하지 않습니다. 어떤 사람들은 여분의 curlies를 항상 사용하는 것을 선호하지만, 난잡함을 더하고 일반적으로 불필요하다고 생각합니다.

는 참조의 흥미로운 주제에 대한 자세한 내용은 밖으로

  1. Perl reference tutorial
  2. Perl reference reference
  3. Perl data structures cookbook
+0

오. 이것은 매우 유익하고 유익했습니다. 놀라운 대답! 나는 Perl의 멋진 문법을 즐기며 전반적으로 스크립트 언어의 팬이되어 가고있다. 고맙습니다! –

+1

목록에없는 링크의 +1은 매일 새로운 것을 배웁니다! – Gabs00

2

펄에서, 당신은 서브 루틴 스칼라의 목록을 통과 확인.

스칼라 값이 가능

  1. 기본 데이터 타입, 즉. String, Int, double
  2. 배열에 대한 참조입니다. 서브 루틴을 호출 할 때

    my @list = (1, 2, 3); 
    
    #note the variable declaration being surrounded by parenthesis. 
    #that says use list context 
    sub getList { 
        my ($foo, $bar, $baz) = @_; #(@_ is the list you passed to the sub) 
    } 
    

    이제 (배열 스칼라의 목록이기 때문에) 당신이이 개 목록이있는 경우

  3. 해시에 대한 참조는

그래서, 당신은, 전체 배열을 전달할 수 있습니다 두 목록이 @_에 포함 된 하나의 배열로 평평하게 될 것입니다 때문에 당신은, 당신이

getList(@listA, @listB); 

을 할 수없는 서브 루틴에 전달하려는.

그래서이 문제를 해결하려면 참조를 사용하거나 배열을 참조로 전달하십시오.

my $first_list = \@listA #this points $first_list to a reference in 
         #memory where @listA is located. 

getList($first_list, \@listB); 

sub getList { 
    my ($foo, $bar) = @_; #$foo and $bar now point to @listA and @listB 

    #To dereference these, you either have to use the -> operator to access 
    #Elements, or use the form @{ }. %{ } for hashes. 

    my @listA = @{ $foo }; 
    my @listB = @{ $bar }; 

    #Now they are regular arrays again! 
} 
+0

이것은 매우 유용한 답변이기도합니다. 고맙습니다! –

관련 문제