2012-05-22 11 views
6

प्रश्न 1:मैं पर्ल में किसी फ़ंक्शन में सरणी कैसे पास कर सकता हूं?

मैं एक समारोह में एक सरणी पास करना चाहता हूं। लेकिन कार्य में पारित तर्क बदल दिया गया है। क्या इसे मूल्य से बुलाया जाता है?

प्रश्न 2:

#my ($name, $num, @array)= @_; <=1) 
my $name = shift;    <=2) 
my $num = shift; 
my @array = shift; 

केस 1 और 2 अलग उत्पादन है। ऐसा क्यों हुआ?

#!/usr/bin/perl 
use strict; 

my @test1; 
push @test1, ['a', 1]; 
push @test1, ['b', 1]; 
push @test1, ['c', 1]; 
push @test1, ['d', 1]; 
push @test1, ['e', 1]; 

for (my $i=0; $i< scalar(@test1); $i++) { 
    print "out1: $test1[$i][0] $test1[$i][1]\n"; 
} 

test_func("test_func", 10, @test1); 

sub test_func { 
    #my ($name, $num, @array)= @_; <=1) 
    my $name = shift;    <=2) 
    my $num = shift; 
    my @array = shift; 

    print "$name\n"; 
    print "$num\n"; 

    for (my $i=0; $i< scalar(@test1); $i++) { 
     print "$array[$i][0] $array[$i][1]\n"; 
    } 

    for (my $i=0; $i< scalar(@test1); $i++) { 
     if ($array[$i][0] eq 'a') { 
      $array[$i][0] = 'z'; 
     } 
    } 
    for (my $i=0; $i< scalar(@test1); $i++) { 
     print "change: $array[$i][0] $array[$i][1]\n"; 
    } 
} 

for (my $i=0; $i< scalar(@test1); $i++) { 
    print "out2: $test1[$i][0] $test1[$i][1]\n"; 
} 
#

नीचे परीक्षण उत्पादन होता है।

out1: a 1 
out1: b 1 
out1: c 1 
out1: d 1 
out1: e 1 
test_func 
10 
a 1 
b 1 
c 1 
d 1 
e 1 
change: z 1 
change: b 1 
change: c 1 
change: d 1 
change: e 1 
out2: z 1 <= Why did it change? 
out2: b 1 
out2: c 1 
out2: d 1 
out2: e 1 

उत्तर

10
मैं एक फ़ंक्शन में एक सरणी पास करना चाहता हूं [...] में अलग-अलग आउटपुट हैं। ऐसा क्यों हुआ?

आप फ़ंक्शन उप में कोई सरणी पास नहीं कर सकते हैं। सब्सक्राइबर केवल तर्क के रूप में स्केलरों की एक सूची ले सकता है। जब आप

my ($name, $num, @array) = @_; 

shift@_ के पहले तत्व है, जो जरूरी एक अदिश है रिटर्न कर

test_func("test_func", 10, @test1); 

test_func("test_func", 10, $test1[0], $test1[1], $test1[2], $test1[3], $test1[4]); 

आप एक नई सरणी पैदा कर रहे test_func में के समान है। @_ एक सरणी है, और सरणी के तत्व स्केलर हैं। समकक्ष

my $name = shift(@_); 
my $num = shift(@_); 
my @array = splice(@_); 

उप से एक सरणी पास करने के लिए, आमतौर पर इसका संदर्भ पास होगा।

test_func("test_func", 10, \@test1); 

my ($name, $num, $array) = @_; 

my $name = shift; 
my $num = shift; 
my $array = shift; 

say "@$array"; 

लेकिन पारित कर दिया तर्क समारोह में बदल जाता है। क्या इसे मूल्य से बुलाया जाता है?

पर्ल कभी भी मूल्य से गुजरता नहीं है। यह हमेशा संदर्भ से गुजरता है। यदि आप @_ का कोई भी तत्व बदलते हैं, तो यह कॉलर में संबंधित तर्क को बदल देगा।

$ perl -E'sub f { $_[0] = "def"; } my $x = "abc"; f($x); say $x;' 
def 

लेकिन यह मुद्दा नहीं है। आप @_ के किसी भी तत्व को नहीं बदलते हैं। आप जो कर रहे हैं वह $test[0] और $array[0] दोनों द्वारा संदर्भित एकल सरणी को बदल रहा है।

यह तुम क्या कर रहे है:

my $ref1 = [ 'a', 1 ]; # aka $test1[0] 
my $ref2 = $ref1;  # aka $array[0] 
$ref2->[0] = 'z';  # Changes the single array (not $ref1 or $ref2). 

यह के लिए

my @anon = ('a', 1); 
my $ref1 = \@anon;  # aka $test1[0] 
my $ref2 = $ref1;  # aka $array[0] 
$ref2->[0] = 'z';  # Changes @anon (not $ref1 or $ref2). 

Storable के dclone एक सरणी के एक "गहरी प्रतिलिपि" बनाने के लिए इस्तेमाल किया जा सकता कम है।

my $ref1 = [ 'a', 1 ]; 
my $ref2 = dclone($ref1); # clones the reference, the array, 'a' and 1. 
$ref1->[0] = 'y';   # Changes the original array 
$ref2->[0] = 'z';   # Changes the new array 
+0

आपकी तरह के स्पष्टीकरण के लिए धन्यवाद।मैं अपनी मुश्किल समस्या को हल करता हूं ^^ – user1395438

+0

यदि इस समाधान ने मदद की है, तो कृपया –

+0

के बगल में स्थित चेक मार्क चिह्नित करें ... और यदि नहीं, तो हमें बताएं कि क्या गुम है। – ikegami

संबंधित मुद्दे

 संबंधित मुद्दे