2010-06-16 9 views
23

पर पुश करें क्या यह push पर पर्ल में सरणी संदर्भ में संभव है? गुगलिंग ने सुझाव दिया है कि मैं पहले सरणी को सम्मानित करता हूं, लेकिन यह वास्तव में काम नहीं करता है। यह संदर्भित सरणी पर नहीं, संदर्भित सरणी पर धक्का देता है।सरणी संदर्भ

उदाहरण के लिए,

my @a =(); 

my $a_ref = [@a]; 

push(@$a_ref,"hello"); 

print $a[0]; 

@a अपडेट नहीं किया जाएगा और इस कोड को विफल हो जाएगा क्योंकि सरणी अभी भी खाली है

(मैं अभी भी पर्ल संदर्भ सीख रहा हूँ, तो यह एक अविश्वसनीय रूप से सरल हो सकता है प्रश्न। क्षमा करें यदि ऐसा है तो)

+9

'मेरा $ a_ref = \ @a;' - आपने एक नया array_references बनाया है, जैसा कि पहले तत्व खाली सरणी -> तो बस एक खाली सरणी है। – Konerak

+5

'$ a_ref = [@a];' मूल '@ a' का संदर्भ नहीं देता है - यह इसकी सामग्री की प्रतिलिपि बनाता है। – Ether

उत्तर

39

यह परिवर्तनीय नामों के बजाय स्मृति पते के संदर्भ में सोचने में मदद कर सकता है।

my @a =();  # Set aside memory address 123 for a list. 

my $a_ref = [@a]; # Square brackets set aside memory address 456. 
        # @a COPIES the stuff from address 123 to 456. 

push(@$a_ref,"hello"); # Push a string into address 456. 

print $a[0]; # Print address 123. 

स्ट्रिंग एक अलग स्मृति स्थान में चला गया।

इसके बजाय, बिंदु सूची @a की स्मृति स्थान पर $a_ref चर। push स्मृति स्थान 123 को प्रभावित करता है। चूंकि @a स्मृति स्थान 123 को भी संदर्भित करता है, इसका मान भी बदलता है।

my $a_ref = \@a;  # Point $a_ref to address 123. 
push(@$a_ref,"hello"); # Push a string into address 123. 
print $a[0];   # Print address 123. 
+6

अच्छा स्पष्टीकरण। लेकिन आप शब्दावली का उपयोग कर सकते हैं कि कम से कम कुछ गहरे स्तर का उपयोग करता है और इंगित करता है कि '[...] 'एक * कन्स्ट्रक्टर * अभिव्यक्ति है। – Axeman

+0

नोट: जब आप इसे पुश करने के लिए पास करते हैं तो आपको सरणी संदर्भ को अव्यवस्थित करने की आवश्यकता नहीं होती है (कम से कम आधुनिक पर्ल का उपयोग करके)। लेकिन मुझे लगता है कि पर्ल दोनों मामलों में समान रूप से प्रदर्शन करता है। – Jonathon

+0

पुश का उपयोग करते समय अपरिवर्तित करना सरणी की एक प्रति नहीं बनाता है? संदर्भों पर – Lukazoid

3

$a, $a_ref नहीं है ($a एक sort{} को दिया पहला तुलना चर रहा है, और $a[0]@a सरणी के 0 तत्व) .Never भी $a, या एक कस्टम प्रकार सबरूटीन के $b बाहर, और @a और @b सरणी शायद बचा जाना चाहिए करने के लिए उपयोग (बेहतर विकल्प के बहुत देखते हैं) है ...

आप जो कर रहे हैं वह $a_ref, एक अज्ञात सरणी असाइन कर रहा है, और उसके बाद "hello" पर जोर दे रहा है, लेकिन @a सरणी का पहला तत्व प्रिंट कर रहा है।

1

हाँ यह संभव है। यह मेरे लिए काम करता है।

my @a =(); 
my $aref = \@a; # creates a reference to the array a 

push(@$aref, "somevalue"); # dereference $aref and push somevalue in it 

print $a[0]; # print the just pushed value, again @$aref[0] should also work 

के रूप में उल्लेख किया गया है, $aref = [@a] कॉपी जाएगा और एक

6

के संदर्भ में नहीं बनाते हैं तो आप deferencing बिना एक सरणी रेफरी पर सीधे धक्का कर सकते हैं।

my $arrayRef = []; 
push $arrayRef, "one"; 
push $arrayRef, "two"; 
print @$arrayRef; 

आउटपुट

onetwo 

प्रलेखन: http://perldoc.perl.org/functions/push.html

पर्ल 5.14 से प्रारंभ होकर, धक्का एक अदिश EXPR, जो एक बेचारा सरणी के लिए एक संदर्भ होने चाहिए जिसे ले सकते हैं।

प्री 5.14 आपको पहले सरणी रेफरी को अव्यवस्थित करना होगा।

push @$arrayRef, "item"; 

संपादित करें: Annnnd सरणी रेफरी के लिए सीधे प्रेरित कर हाल ही में एक पर्ल रिलीज में पदावनत किया गया है (5.24?)।यह देखते हुए, आपके कोड की संगतता बढ़ाने के लिए दबाव डालने से पहले हमेशा {{$ arrayRef} को हटाना सुरक्षित होगा।

+0

'पुश' वास्तव में पर्ल 5.24 में पूरी तरह से हटा दिया गया था। – Xaerxess

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