यह वास्तव में व्यवहार की उम्मीद है - और इस तथ्य के कारण है कि Array
स्विफ्ट में (साथ ही साथ मानक लाइब्रेरी में कई अन्य संग्रह) एक मूल्य प्रकार है जो कॉपी-ऑन-राइट सेमेन्टिक्स के साथ है। इसका मतलब यह है कि इसके अंतर्निहित बफर (जिसे परोक्ष रूप से संग्रहीत किया जाता है) उत्परिवर्तित होने पर कॉपी किया जाएगा (और, अनुकूलन के रूप में, केवल तभी जब इसे विशिष्ट रूप से संदर्भित नहीं किया जाता है)।
(ध्यान दें कि यह जवाब कि पहले कहा कि प्रति इटरेटर जो, के रूप में @MartinR सही ढंग से बताया करने के लिए पारित किया जा रहा पर क्या होगा, क्या नहीं होता है।)
आप एक Sequence
से अधिक पुनरावृति करने के लिए आते हैं (जैसे कि सरणी), forEach(_:)
या मानक for in
लूप के साथ हो, एक इटरेटर अनुक्रम की makeIterator()
विधि से बनाया गया है, और यह क्रमशः तत्व उत्पन्न करने के लिए next()
विधि को बार-बार लागू किया जाता है।
आप इस तरह लग रही के रूप में एक दृश्य के ऊपर बार-बार दोहराना के बारे में सोच सकते हैं:
let sequence = [1, 2, 3, 4]
var iterator = sequence.makeIterator()
// next() will return the next element, or nil if it's reached the end of the sequence.
while let element = iterator.next() {
// do something with the element
}
Array
के मामले में, के रूप में यह इटरेटर है एक IndexingIterator
प्रयोग किया जाता है - जो केवल द्वारा दिए गए संग्रह के तत्वों के माध्यम से पुनरावृति जाएगा पुनरावृत्ति के वर्तमान सूचकांक के साथ उस संग्रह को संग्रहीत संग्रहित करता है। प्रत्येक बार next()
कहा जाता है, मूल संग्रह को इंडेक्स के साथ सब्सक्राइब किया जाता है, जिसे तब बढ़ाया जाता है, जब तक यह endIndex
तक पहुंचता है (आप इसे exact implementation here देख सकते हैं)।
इसलिए, जब आप लूप में अपनी सरणी को म्यूटेट करने के लिए आते हैं, तो यह अंतर्निहित बफर विशिष्ट रूप से संदर्भित नहीं है, क्योंकि इटरेटर के पास भी इसका दृश्य है। यह बफर की एक प्रति को मजबूर करता है - जो myCollection
तब उपयोग करता है।
तो, अब दो सरणी हैं - एक जिसे फिर से चालू किया जा रहा है, और जिसे आप उत्परिवर्तित कर रहे हैं। लूप में कोई और उत्परिवर्तन एक और प्रतिलिपि नहीं ट्रिगर करेगा, जब तक myCollection
का बफर विशिष्ट रूप से संदर्भित रहता है।
इसलिए इसका मतलब यह है कि इस पर गणना करते समय मूल्य अर्थशास्त्र के साथ संग्रह को उत्परिवर्तित करना पूरी तरह से सुरक्षित है। गणना संग्रह की पूरी लंबाई में फिर से शुरू होगी - आपके द्वारा किए गए किसी भी उत्परिवर्तन की पूरी तरह से स्वतंत्र, क्योंकि वे एक प्रतिलिपि पर किए जाएंगे।
चेतावनी के शब्द::
यहाँ प्रभाव का प्रदर्शन एक सरल उदाहरण है 'removeItem (_ :)' 'है हे (एन)', के रूप में 'foreach (_ :)' है। यह पंक्ति कुल में 'ओ (एन^2) 'है। सेट अंकगणित का उपयोग कर लायक हो सकता है। – Alexander
यह जरूरी नहीं है कि 'ओ (एन) '- सेट' ओ (1)' हैं। मैं 'removeItem (_ :)' विधि स्वयं (एक त्वरित संग्रह पर ऐसी कोई विधि नहीं है) की आपूर्ति करता हूं, और वहां कुछ अन्य टियरडाउन-सामान करता हूं। –
इसके अलावा, इस संग्रह में आम तौर पर 2-4 आइटम होते हैं, इसलिए मैंने जानबूझकर संभावित रनटाइम हिट लिया;) –