क्या कोई कारण है कि स्विफ्ट सरणी असाइनमेंट असंगत है (न तो एक संदर्भ और न ही एक गहरी प्रतिलिपि)?


216

मैं दस्तावेज़ीकरण पढ़ रहा हूं और मैं लगातार भाषा के कुछ डिजाइन निर्णयों पर अपना सिर हिला रहा हूं। लेकिन जो चीज मुझे वाकई हैरान कर गई, वह यह है कि एरे को कैसे संभाला जाता है।

मैं खेल के मैदान में भाग गया और इन्हें आज़माया। आप उन्हें भी आजमा सकते हैं। तो पहला उदाहरण:

var a = [1, 2, 3]
var b = a
a[1] = 42
a
b

यहां aऔर bदोनों हैं [1, 42, 3], जिसे मैं स्वीकार कर सकता हूं। एरे को संदर्भित किया जाता है - ठीक है!

अब इस उदाहरण को देखें:

var c = [1, 2, 3]
var d = c
c.append(42)
c
d

cहै [1, 2, 3, 42], लेकिन dहै [1, 2, 3]। यही है, dपिछले उदाहरण में परिवर्तन देखा , लेकिन इसे इस एक में नहीं देखा। प्रलेखन कहता है कि क्योंकि लंबाई बदल गई है।

अब, यह कैसे होता है:

var e = [1, 2, 3]
var f = e
e[0..2] = [4, 5]
e
f

eहै [4, 5, 3], जो शांत है। मल्टी-इंडेक्स रिप्लेसमेंट करना अच्छा है, लेकिन fस्टिल में बदलाव नहीं दिखता है जबकि लंबाई नहीं बदली है।

इसलिए इसे योग करने के लिए, सरणी के सामान्य संदर्भ 1 तत्व बदलने पर परिवर्तन देखते हैं, लेकिन यदि आप कई तत्वों को बदलते हैं या आइटम को जोड़ते हैं, तो एक प्रतिलिपि बनाई जाती है।

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

EDIT : एरे बदल गए हैं और अब मूल्य शब्दार्थ हैं। बहुत अधिक समझदार!


95
रिकॉर्ड के लिए, मुझे नहीं लगता कि यह सवाल बंद होना चाहिए। स्विफ्ट एक नई भाषा है, इसलिए कुछ समय के लिए इस तरह के प्रश्न होंगे जो हम सभी सीखते हैं। मुझे यह सवाल बहुत दिलचस्प लगता है और मुझे उम्मीद है कि किसी के पास बचाव पर एक सम्मोहक मामला होगा।
जोएल बर्जर

4
@ जॉयल फाइन, इसे प्रोग्रामर से पूछें, स्टैक ओवरफ्लो विशिष्ट अनोपिनियेटेड प्रोग्रामिंग समस्याओं के लिए है।
bjb568 18

21
@ bjb568: यह राय नहीं है, हालांकि। इस सवाल को तथ्यों के साथ जवाबदेह होना चाहिए। यदि कुछ स्विफ्ट डेवलपर आते हैं और जवाब देते हैं "हमने एक्स, वाई और जेड के लिए ऐसा किया था," तो यह सीधे तथ्य है। आप X, Y और Z से सहमत नहीं हो सकते हैं, लेकिन यदि X, Y और Z के लिए कोई निर्णय लिया गया है, तो यह भाषा के डिजाइन का सिर्फ एक ऐतिहासिक तथ्य है। बहुत कुछ जब मैंने पूछा कि std::shared_ptrगैर-परमाणु संस्करण क्यों नहीं है, तो तथ्य पर आधारित एक उत्तर था, राय नहीं (तथ्य यह है कि समिति ने इस पर विचार किया था लेकिन विभिन्न कारणों से ऐसा नहीं चाहती थी)।
कॉर्नस्टालक्स

7
@ जैसनमोर्चर: केवल अंतिम पैराग्राफ राय पर आधारित है (जो कि हां, शायद हटा दिया जाना चाहिए)। प्रश्न का वास्तविक शीर्षक (जो मैं स्वयं वास्तविक प्रश्न के रूप में लेता हूं) तथ्यों के साथ उत्तर देने योग्य है। वहाँ है एक कारण सरणियों तरह से वे काम करते हैं काम करने के लिए डिजाइन किए गए थे।
कॉर्नस्टालक्स

7
हां, जैसा कि एपीआई-बीस्ट ने कहा था, इसे आमतौर पर "कॉपी-ऑन-हाफ-एस्ड-लैंग्वेज-डिजाइन" कहा जाता है।
आर। मार्टिनो फर्नांडिस

जवाबों:


109

ध्यान दें कि सरणी शब्दार्थ और वाक्यविन्यास को Xcode बीटा 3 संस्करण ( ब्लॉग पोस्ट ) में बदल दिया गया था , इसलिए यह प्रश्न अब लागू नहीं होता है। निम्नलिखित उत्तर बीटा 2 पर लागू होता है:


यह प्रदर्शन कारणों से है। मूल रूप से, वे जब तक वे कर सकते हैं, तब तक सरणियों की नकल करने से बचने की कोशिश करते हैं (और "सी-लाइक प्रदर्शन" का दावा करते हैं)। भाषा की किताब उद्धृत करने के लिए :

सरणियों के लिए, नकल केवल तब होती है जब आप एक क्रिया करते हैं जिसमें सरणी की लंबाई को संशोधित करने की क्षमता होती है। इसमें आइटम्स को जोड़ना, सम्मिलित करना या हटाना या किसी श्रेणी की वस्तुओं को श्रेणी में बदलने के लिए एक उप-सबस्क्रिप्ट का उपयोग करना शामिल है।

मैं मानता हूं कि यह थोड़ा भ्रमित करने वाला है, लेकिन कम से कम यह स्पष्ट और सरल विवरण है कि यह कैसे काम करता है।

उस खंड में यह जानकारी भी शामिल है कि किसी सरणी को विशिष्ट रूप से संदर्भित करने के लिए कैसे सुनिश्चित किया जाए, कैसे सरणियों की प्रतिलिपि बनाई जाए, और यह जांचने के लिए कि क्या दो सरणियाँ साझा संग्रहण हैं।


61
मुझे इस तथ्य का पता चलता है कि आपके पास दोनों अनिश्चित हैं और डिजाइन में एक बड़े लाल झंडे की नकल करते हैं।
चुतु

9
यह सही है। एक इंजीनियर ने मुझे बताया कि भाषा के डिजाइन के लिए यह वांछनीय नहीं है, और कुछ ऐसा है जो वे स्विफ्ट के आगामी अपडेट में "ठीक" करने की उम्मीद करते हैं। राडार से वोट करें।
एरिक कर्बर

2
यह लिनक्स चाइल्ड प्रोसेस मेमोरी मैनेजमेंट, राइट में कॉपी-ऑन-राइट (गाय) जैसा कुछ है? शायद हम इसे कॉपी-ऑन-लेंथ-एलेक्सेशन (COLA) कह सकते हैं। मैं इसे एक सकारात्मक डिजाइन के रूप में देखता हूं।
3

3
@ अन्याय मुझे एसओ के आने वाले उलझन भरे नोक-झोंक की भविष्यवाणी कर सकता है और पूछ सकता है कि उनके सरणियों को साझा क्यों नहीं किया गया (बस कम स्पष्ट तरीके से)।
जॉन ड्वोरक

11
@ अन्याय: गाय आधुनिक दुनिया में वैसे भी निराशावाद है, और दूसरी बात, गाय एक कार्यान्वयन-मात्र तकनीक है, और यह कोला सामान पूरी तरह से यादृच्छिक साझाकरण और अविरलता की ओर ले जाता है।
पिल्ला

25

स्विफ्ट भाषा के आधिकारिक दस्तावेज से :

ध्यान दें कि जब आप सबस्क्रिप्ट सिंटैक्स के साथ एक नया मान सेट करते हैं, तो सरणी की प्रतिलिपि नहीं बनाई गई है, क्योंकि सबस्क्रिप्ट सिंटैक्स के साथ एक एकल मान सेट करने से सरणी की लंबाई बदलने की क्षमता नहीं है। हालाँकि, यदि आप किसी नए आइटम को सरणी में जोड़ते हैं, तो आप सरणी की लंबाई को संशोधित करते हैं । यह स्विफ्ट को उस बिंदु पर सरणी की एक नई प्रतिलिपि बनाने के लिए संकेत देता है जिसे आप नए मान को जोड़ते हैं। इसके बाद, सरणी की एक अलग, स्वतंत्र प्रतिलिपि है .....

इस डॉक्यूमेंट में Arrays के लिए संपूर्ण अनुभाग असाइनमेंट और कॉपी व्यवहार पढ़ें । आप पाएंगे कि जब आप किसी आइटम को श्रेणी में प्रतिस्थापित करते हैं तो सरणी सभी आइटमों के लिए स्वयं की एक प्रति ले जाती है।


4
धन्यवाद। मैंने अपने प्रश्न में उस पाठ का उल्लेख किया है। लेकिन मैंने एक उदाहरण दिखाया जहां एक सबस्क्रिप्ट रेंज बदलने से लंबाई नहीं बदलती थी और यह अभी भी कॉपी की जाती थी। इसलिए यदि आप एक प्रति नहीं चाहते हैं तो आपको एक समय में एक तत्व को बदलना होगा।
चुतु जू

21

Xcode 6 बीटा के साथ व्यवहार बदल गया है। 3. Arrays अब संदर्भ प्रकार नहीं हैं और एक कॉपी-ऑन-राइट तंत्र है, जिसका अर्थ है जैसे ही आप एक या दूसरे चर से सरणी की सामग्री को बदलते हैं, सरणी की प्रतिलिपि बनाई जाएगी और केवल एक प्रति बदल दी जाएगी।


पुराना उत्तर:

जैसा कि दूसरों ने बताया है, स्विफ्ट एक बार में एकल अनुक्रमित के लिए मान बदलते समय सहित, यदि संभव हो तो प्रतिलिपि सरणियों से बचने की कोशिश करता है ।

यदि आप सुनिश्चित करना चाहते हैं कि एक सरणी चर (!) अद्वितीय है, अर्थात किसी अन्य चर के साथ साझा नहीं किया गया है, तो आप unshareविधि को कॉल कर सकते हैं । यह सरणी को तब तक कॉपी करता है जब तक कि उसमें पहले से केवल एक संदर्भ न हो। बेशक, आप उस copyविधि को भी कॉल कर सकते हैं , जो हमेशा एक प्रतिलिपि बनायेगी , लेकिन यह सुनिश्चित करना पसंद नहीं किया जाता है कि कोई अन्य वैरिएबल एक ही सरणी पर न हो।

var a = [1, 2, 3]
var b = a
b.unshare()
a[1] = 42
a               // [1, 42, 3]
b               // [1, 2, 3]

हम्म, मेरे लिए, वह unshare()विधि अपरिभाषित है।
5

1
@ हेलंग इसे बीटा 3 में हटा दिया गया है, मैंने अपना उत्तर अपडेट कर दिया है।
पास्कल

12

व्यवहार Array.Resize.NET में विधि के समान है । यह समझने के लिए कि .सी, सी ++, जावा, सी #, और स्विफ्ट में टोकन के इतिहास को देखने के लिए क्या उपयोगी हो सकता है ।

सी में, एक संरचना चरों के एकत्रीकरण से ज्यादा कुछ नहीं है। .संरचना प्रकार के एक चर पर लागू करना संरचना के भीतर संग्रहीत एक चर तक पहुंच जाएगा। ऑब्जेक्ट्स के पॉइंटर्स वेरिएबल्स के एकत्रीकरण को नहीं पकड़ते हैं , लेकिन उन्हें पहचानते हैं। यदि किसी के पास एक संकेतक है जो एक संरचना की पहचान करता है, तो ->ऑपरेटर का उपयोग सूचक द्वारा पहचाने गए ढांचे के भीतर संग्रहीत चर तक पहुंचने के लिए किया जा सकता है।

सी ++ में, संरचनाएं और कक्षाएं न केवल एकत्रित चर बनाती हैं, बल्कि उन्हें कोड भी संलग्न कर सकती हैं। .एक विधि का उपयोग करने के लिए एक चर पर होगा कि विधि चर की सामग्री पर ही काम करने के लिए पूछना ; ->एक चर पर प्रयोग करना जो किसी वस्तु की पहचान करता है, उस विधि को चर द्वारा पहचानी गई वस्तु पर कार्य करने के लिए कहेगा ।

जावा में, सभी कस्टम वैरिएबल प्रकार केवल वस्तुओं की पहचान करते हैं, और एक वैरिएबल पर एक विधि को लागू करने से वह विधि बताएगी जो चर द्वारा ऑब्जेक्ट की पहचान की जाती है। चर सीधे किसी भी प्रकार के समग्र डेटा प्रकार को पकड़ नहीं सकते हैं, और न ही ऐसा कोई साधन है जिसके द्वारा कोई विधि किसी चर पर पहुंच सकती है जिस पर इसे लागू किया जाता है। ये प्रतिबंध, हालांकि शब्दार्थ सीमित हैं, रनटाइम को बहुत सरल करते हैं, और बायटेकोड सत्यापन की सुविधा प्रदान करते हैं; इस तरह के सरलीकरणों ने जावा के संसाधन ओवरहेड को कम कर दिया, जब बाजार ऐसे मुद्दों के प्रति संवेदनशील था, और इस तरह से बाजार में इसका लाभ हुआ। उनका यह भी मतलब था कि .C या C ++ में इस्तेमाल किए गए समान के बराबर टोकन की कोई आवश्यकता नहीं है । हालाँकि जावा ->C और C ++ की तरह ही इस्तेमाल किया जा सकता था , लेकिन रचनाकारों ने एकल-वर्ण का उपयोग करने का विकल्प चुना. चूँकि किसी अन्य उद्देश्य के लिए इसकी आवश्यकता नहीं थी।

C # और अन्य .NET भाषाओं में, चर या तो वस्तुओं की पहचान कर सकते हैं या सीधे मिश्रित डेटा प्रकारों को पकड़ सकते हैं। जब एक समग्र डेटा प्रकार के चर पर उपयोग किया जाता है, तो चर .की सामग्री पर कार्य करता है ; जब संदर्भ प्रकार के एक चर पर उपयोग किया जाता है, तो पहचान. की गई वस्तु पर कार्य करता हैइसके द्वारा। कुछ प्रकार के संचालन के लिए, शब्दार्थ भेद विशेष रूप से महत्वपूर्ण नहीं है, लेकिन दूसरों के लिए यह है। सबसे अधिक समस्याग्रस्त स्थितियां वे हैं जिनमें एक समग्र डेटा प्रकार की विधि जो उस चर को संशोधित करती है जिस पर इसे लागू किया जाता है, को केवल-पढ़ने के लिए चर पर लाया जाता है। यदि रीड-ओनली वैल्यू या वैरिएबल पर किसी विधि को लागू करने का प्रयास किया जाता है, तो कंपाइलर्स आमतौर पर वैरिएबल की नकल करेंगे, विधि को उस पर कार्य करने देंगे, और वैरिएबल को त्याग देंगे। यह आम तौर पर उन तरीकों से सुरक्षित है जो केवल चर को पढ़ते हैं, लेकिन उन तरीकों से सुरक्षित नहीं हैं जो इसे लिखते हैं। दुर्भाग्य से, .does के पास अभी तक यह संकेत देने का कोई साधन नहीं है कि कौन से तरीकों का उपयोग ऐसे प्रतिस्थापन के साथ सुरक्षित रूप से किया जा सकता है और जो नहीं कर सकते।

स्विफ्ट में, समुच्चय के तरीके स्पष्ट रूप से इंगित कर सकते हैं कि क्या वे उस चर को संशोधित करेंगे, जिस पर वे आमंत्रित हैं, और कंपाइलर केवल-पढ़ी गई चर पर उत्परिवर्तन विधियों के उपयोग की मनाही करेगा (बजाय उन्हें परिवर्तनशील की अस्थायी प्रतियां म्यूट करने के बजाय जो तब होगा छूट जाना)। इस अंतर के कारण, .उन कॉल विधियों को टोकन का उपयोग करना, जो उन चर को संशोधित करते हैं, जिन पर उन्हें लागू किया जाता है। .NET की तुलना में स्विफ्ट में अधिक सुरक्षित है। दुर्भाग्य से, तथ्य यह है कि एक ही .टोकन का उपयोग उस उद्देश्य के लिए किया जाता है क्योंकि एक चर द्वारा पहचानी गई बाहरी वस्तु पर कार्य करने का मतलब है कि भ्रम की संभावना बनी हुई है।

अगर टाइम मशीन थी और C # और / या स्विफ्ट के निर्माण में वापस चली गई, तो कोई भी इस तरह के मुद्दों के आसपास के भ्रम से बहुत हद तक बच सकता था, क्योंकि भाषाओं का उपयोग .और ->टोकन C ++ उपयोग के बहुत करीब है। दोनों समुच्चय और संदर्भ प्रकारों के तरीके .उस चर पर कार्य करने के लिए उपयोग कर सकते हैं जिस पर उन्हें आमंत्रित किया गया था, और ->एक मूल्य (कंपोजिट के लिए) या इस तरह पहचानी गई चीज़ (संदर्भ प्रकार के लिए) पर कार्य करने के लिए। हालांकि, न तो भाषा को इस तरह से डिज़ाइन किया गया है।

C # में, एक वैरिएबल को संशोधित करने के लिए एक विधि के लिए सामान्य अभ्यास, जिस पर इसे लागू किया जाता है, चर refको एक विधि के पैरामीटर के रूप में पास करना है । इस प्रकार Array.Resize(ref someArray, 23);जब someArray20 तत्वों की एक सरणी की someArrayपहचान होती है, तो मूल सरणी को प्रभावित किए बिना, 23 तत्वों की एक नई सरणी की पहचान करने का कारण होगा । यह refस्पष्ट करता है कि विधि को उस चर को संशोधित करने की अपेक्षा की जानी चाहिए जिस पर इसे लागू किया गया है। कई मामलों में, स्थैतिक तरीकों का उपयोग किए बिना चर को संशोधित करने में सक्षम होना लाभप्रद है; स्विफ्ट पते का मतलब है कि .वाक्य रचना का उपयोग करके । नुकसान यह है कि यह स्पष्ट करता है कि चर पर कौन से तरीके काम करते हैं और मान किन तरीकों से कार्य करते हैं।


5

यदि आप पहली बार अपने स्थिरांक को चरों के साथ बदलते हैं, तो मेरे लिए यह अधिक मायने रखता है:

a[i] = 42            // (1)
e[i..j] = [4, 5]     // (2)

पहली पंक्ति के आकार को बदलने की आवश्यकता नहीं है a। विशेष रूप से, इसे किसी भी मेमोरी आवंटन को करने की आवश्यकता नहीं है। के मूल्य के बावजूद i, यह एक हल्का संचालन है। यदि आप कल्पना करते हैं कि हुड के नीचे aएक पॉइंटर है, तो यह एक निरंतर पॉइंटर हो सकता है।

दूसरी पंक्ति बहुत अधिक जटिल हो सकती है। के मूल्यों पर निर्भर करता है iऔर j, आप स्मृति प्रबंधन करने की जरूरत हो सकती है। यदि आप कल्पना करते हैं कि eयह एक सूचक है जो सरणी की सामग्री को इंगित करता है, तो आप अब यह नहीं मान सकते हैं कि यह एक स्थिर सूचक है; आपको मेमोरी का एक नया ब्लॉक आवंटित करने की आवश्यकता हो सकती है, पुराने मेमोरी ब्लॉक से नए मेमोरी ब्लॉक में डेटा कॉपी करें और पॉइंटर बदलें।

ऐसा लगता है कि भाषा डिजाइनरों ने (1) को यथासंभव हल्के रखने की कोशिश की है। जैसे (2) में वैसे भी कॉपी करना शामिल हो सकता है, उन्होंने इस समाधान का सहारा लिया है कि यह हमेशा ऐसा काम करता है जैसे कि आपने कॉपी किया हो।

यह जटिल है, लेकिन मुझे खुशी है कि उन्होंने इसे और अधिक जटिल नहीं बनाया, जैसे कि विशेष मामलों जैसे कि "यदि (2) में i और j संकलित समय-स्थिरांक हैं और संकलक यह अनुमान लगा सकता है कि e का आकार नहीं जा रहा है बदलने के लिए, फिर हम नकल नहीं करते हैं ”


अंत में, स्विफ्ट भाषा के डिजाइन सिद्धांतों की मेरी समझ के आधार पर, मुझे लगता है कि सामान्य नियम ये हैं:

  • कॉन्स्टेंट ( let) का उपयोग हमेशा हर जगह डिफ़ॉल्ट रूप से करें, और कोई भी बड़ा आश्चर्य नहीं होगा।
  • चर का उपयोग करें ( var) केवल अगर यह बिल्कुल आवश्यक है, और उन मामलों में अलग-अलग सावधान रहें, क्योंकि आश्चर्य होगा [यहां: कुछ और सभी स्थितियों में सरणियों की अजीब अंतर्निहित प्रतियां]।

5

मैंने जो पाया है वह है: सरणी संदर्भित संदर्भित की एक परस्पर प्रतिलिपि होगी यदि और केवल तभी जब ऑपरेशन में सरणी की लंबाई को बदलने की क्षमता है । आपके अंतिम उदाहरण में, f[0..2]कई के साथ अनुक्रमण, ऑपरेशन में इसकी लंबाई को बदलने की क्षमता है (यह हो सकता है कि डुप्लिकेट की अनुमति न हो), इसलिए इसकी प्रतिलिपि बनाई जा रही है।

var e = [1, 2, 3]
var f = e
e[0..2] = [4, 5]
e // 4,5,3
f // 1,2,3


var e1 = [1, 2, 3]
var f1 = e1

e1[0] = 4
e1[1] = 5

e1 //  - 4,5,3
f1 // - 4,5,3

8
"लंबाई के रूप में इलाज किया गया है" मैं समझ सकता हूं कि अगर यह लंबाई बदल जाती है, तो इसकी नकल हो जाएगी, लेकिन उपरोक्त उद्धरण के साथ संयोजन में, मुझे लगता है कि यह वास्तव में चिंताजनक "सुविधा" है और एक जो मुझे लगता है कि बहुत से लोग गलत हो जाएंगे
जोएल बर्जर

25
सिर्फ इसलिए कि कोई भाषा नई है, इसका मतलब यह नहीं है कि इसमें आंतरिक अंतर्विरोधों को समाहित करना ठीक है।
को ऑर्बिट

इसे बीटा 3 में "निश्चित" कर दिया गया है, varसरणियाँ अब पूरी तरह से परस्पर हैं और letसरणियाँ पूरी तरह से अपरिवर्तनीय हैं।
पास्कल

4

डेल्फी के तार और सरणियों का ठीक वैसा ही "फीचर" था। जब आपने कार्यान्वयन को देखा, तो यह समझ में आया।

प्रत्येक चर गतिशील स्मृति के लिए एक संकेतक है। उस मेमोरी में सरणी में डेटा के बाद एक संदर्भ गणना होती है। तो आप आसानी से पूरे सरणी की प्रतिलिपि बनाए बिना या किसी भी संकेत को बदलकर सरणी में एक मान बदल सकते हैं। यदि आप सरणी का आकार बदलना चाहते हैं, तो आपको अधिक मेमोरी आवंटित करनी होगी। उस स्थिति में वर्तमान चर नई आवंटित स्मृति को इंगित करेगा। लेकिन आप अन्य सभी चर को आसानी से ट्रैक नहीं कर सकते हैं जो मूल सरणी को इंगित करते हैं, इसलिए आप उन्हें अकेला छोड़ देते हैं।

बेशक, यह अधिक सुसंगत कार्यान्वयन करने के लिए कठिन नहीं होगा। यदि आप चाहते थे कि सभी चर एक आकार देखें, तो ऐसा करें: प्रत्येक चर गतिशील मेमोरी में संग्रहीत कंटेनर का एक संकेतक है। कंटेनर वास्तविक सरणी डेटा के लिए वास्तव में दो चीजें, एक संदर्भ गणना और सूचक रखता है। सरणी डेटा को डायनेमिक मेमोरी के एक अलग ब्लॉक में संग्रहीत किया जाता है। अब सरणी डेटा में केवल एक सूचक है, इसलिए आप आसानी से इसका आकार बदल सकते हैं, और सभी चर परिवर्तन देखेंगे।


4

बहुत से स्विफ्ट के शुरुआती दत्तक ग्रहणकर्ताओं ने इस त्रुटि-प्रवण सरणी शब्दार्थ के बारे में शिकायत की है और क्रिस लैटनर ने लिखा है कि सरणी शब्दार्थ को संशोधित किया गया है ताकि जो लोग खाते के लिए पूर्ण मूल्य शब्दार्थ ( Apple डेवलपर लिंक ) प्रदान कर सकें । हमें अगले बीटा के लिए कम से कम इंतजार करना होगा कि वास्तव में इसका क्या मतलब है।


1
नया ऐरे व्यवहार अब एसडीके के रूप में उपलब्ध है जिसमें iOS 8 / Xcode 6 बीटा 3 शामिल है
स्माइबॉर्ग

0

मैं इसके लिए .copy () का उपयोग करता हूं।

    var a = [1, 2, 3]
    var b = a.copy()
     a[1] = 42 

1
जब मैं आपका कोड चलाता हूं तो मुझे "वैल्यू ऑफ टाइप '[इंट] का कोई मेंबर' कॉपी 'नहीं
मिलता

0

क्या बाद के स्विफ्ट संस्करणों में सरणियों के व्यवहार में कुछ बदलाव आया? मैं सिर्फ आपका उदाहरण चलाता हूं:

var a = [1, 2, 3]
var b = a
a[1] = 42
a
b

और मेरे परिणाम हैं [१, ४२, ३] और [१, २, ३]

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.