स्विफ्ट और म्यूटिंग संरचना


96

ऐसा कुछ है जिसे मैं पूरी तरह से नहीं समझता जब यह स्विफ्ट में मूल्य प्रकारों को म्यूट करने की बात आती है।

जैसा कि "द स्विफ्ट प्रोग्रामिंग लैंग्वेज" iBook बताता है: डिफ़ॉल्ट रूप से, मूल्य प्रकार के गुणों को इसके उदाहरण के तरीकों से संशोधित नहीं किया जा सकता है।

और इसलिए इसे संभव बनाने के लिए हम mutatingसंरचना और enums के अंदर कीवर्ड के साथ तरीकों की घोषणा कर सकते हैं ।

जो चीज मेरे लिए पूरी तरह से स्पष्ट नहीं है, वह यह है: आप किसी संरचना के बाहर से एक संस्करण बदल सकते हैं, लेकिन आप इसे अपने तरीकों से नहीं बदल सकते। यह मेरे लिए प्रति-सहज ज्ञान युक्त प्रतीत होता है, जैसा कि ऑब्जेक्ट ओरिएंटेड भाषाओं में, आप आमतौर पर चर को एनकैप्सुलेट करने की कोशिश करते हैं ताकि वे केवल भीतर से ही बदल सकें। संरचना के साथ यह चारों ओर का दूसरा रास्ता प्रतीत होता है। विस्तृत करने के लिए, यहाँ एक कोड स्निपेट है:

struct Point {
    var x = 0, y = 0
    mutating func moveToX(x: Int, andY y:Int) { //Needs to be a mutating method in order to work
        self.x = x
        self.y = y
    }
}

var p = Point(x: 1, y: 2)
p.x = 3 //Works from outside the struct!
p.moveToX(5, andY: 5) 

क्या किसी को इसका कारण पता है कि संरचनाएं अपने संदर्भ के अंदर से अपनी सामग्री को क्यों नहीं बदल सकती हैं, जबकि सामग्री को आसानी से कहीं और बदला जा सकता है?

जवाबों:


80

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

मूल्य एक परिवर्तनशील भंडारण (हम इसे कहते करने के लिए सौंपा गया है, तो varया चर स्विफ्ट में), आप उनमें से राज्य को संशोधित करने के लिए स्वतंत्र हैं, और विधि परिवर्तनशील की बुला अनुमति दी है।

इसके अलावा, कक्षाओं में यह अपरिवर्तनीय / परिवर्तनशील मोड नहीं है। IMO, इसका कारण यह है कि कक्षाएं आमतौर पर संदर्भ-सक्षम इकाई का प्रतिनिधित्व करने के लिए उपयोग की जाती हैं । और संदर्भ-सक्षम इकाई आमतौर पर परिवर्तनशील होती है क्योंकि उचित प्रदर्शन के साथ अपरिवर्तनीय तरीके से संस्थाओं के संदर्भ ग्राफ़ को बनाना और प्रबंधित करना बहुत कठिन होता है। वे इस सुविधा को बाद में जोड़ सकते हैं, लेकिन अब कम से कम नहीं।

उद्देश्य-सी प्रोग्रामर के लिए, परस्पर / अपरिवर्तनीय अवधारणाएं बहुत परिचित हैं। ऑब्जेक्टिव-सी में हमारे पास प्रत्येक अवधारणा के लिए दो अलग-अलग वर्ग थे, लेकिन स्विफ्ट में, आप एक संरचना के साथ ऐसा कर सकते हैं। आधा काम।

C / C ++ प्रोग्रामर के लिए, यह भी बहुत परिचित अवधारणा है। यह वही है जो constकीवर्ड C / C ++ में करता है।

इसके अलावा, अपरिवर्तनीय मूल्य बहुत अच्छी तरह से अनुकूलित किया जा सकता है। सिद्धांत रूप में, स्विफ्ट कंपाइलर (या एलएलवीएम) letC ++ की तरह ही पास किए गए मूल्यों पर कॉपी-एलिसन कर सकता है । यदि आप समझदारी से अपरिवर्तनीय संरचना का उपयोग करते हैं, तो यह परिष्कृत कक्षाओं को बेहतर बना देगा।

अपडेट करें

@Joseph दावा किया के रूप में इस प्रदान नहीं करता है क्यों , मैं एक छोटे से अधिक जोड़ने कर रहा हूँ।

संरचनाओं में दो तरह की विधियां होती हैं। सादा और परिवर्तनशील तरीके। सादा विधि का अर्थ है अपरिवर्तनीय (या गैर-उत्परिवर्तन) । यह पृथक्करण अपरिवर्तनीय शब्दार्थ का समर्थन करने के लिए ही मौजूद है । अपरिवर्तनीय मोड में कोई वस्तु अपने राज्य को बिल्कुल नहीं बदलना चाहिए।

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

और फिर, आपके पास यह सवाल हो सकता है कि अपरिवर्तनीय डिफ़ॉल्ट क्यों है? ऐसा इसलिए है क्योंकि भविष्य के उत्परिवर्तन मूल्यों की भविष्यवाणी करना बहुत कठिन है, और यह आमतौर पर सिरदर्द और बग का मुख्य स्रोत बन जाता है। कई लोग इस बात से सहमत थे कि समाधान उत्परिवर्ती सामानों से बच रहा है, और फिर डिफ़ॉल्ट रूप से अपरिवर्तनीय सी / सी ++ परिवार की भाषाओं और इसके व्युत्पन्न में दशकों के लिए इच्छा सूची के शीर्ष पर था।

देखें पूरी तरह कार्यात्मक शैली अधिक जानकारी के लिए। वैसे भी, हमें अभी भी परिवर्तनशील सामान की आवश्यकता है क्योंकि अपरिवर्तनीय सामान में कुछ कमजोरियां हैं, और उनके बारे में चर्चा करना विषय से बाहर लगता है।

आशा है कि ये आपकी मदद करेगा।


2
इसलिए मूल रूप से, मैं इसकी व्याख्या कर सकता हूं: एक संरचना को अग्रिम में पता नहीं है कि यह परस्पर या अपरिवर्तनीय होगा, इसलिए यह अपरिवर्तनीयता को मानता है जब तक कि अलग-अलग तरीके से नहीं कहा जाता है। देखा कि यह वास्तव में समझ में आता है। क्या ये सही है?
माइक सेगर्स

1
@MikeSeghers मुझे लगता है कि समझ में आता है।
eonil

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

4
@JosephKnight यह नहीं है कि संरचना अपरिवर्तनीय के लिए डिफ़ॉल्ट है। यह अपरिवर्तनीय करने के लिए डिफ़ॉल्ट के तरीकों की है। इसे उल्टे अनुमान के साथ C ++ की तरह समझें। C ++ विधियों में यह निरंतर नहीं होने के लिए डिफ़ॉल्ट रूप से, आपको स्पष्ट रूप constसे उस विधि में जोड़ना होगा यदि आप चाहते हैं कि यह एक 'कॉन्स्टेंट' हो और निरंतर इंस्टेंसेस (सामान्य विधियों का उपयोग तब नहीं किया जा सकता है जब इंस्टेंस कॉस्ट हो)। स्विफ्ट विपरीत डिफॉल्ट के साथ भी ऐसा ही करती है: एक विधि में डिफ़ॉल्ट रूप से एक 'कॉन्स्टेंट' होता है और आप इसे अन्यथा चिन्हित करते हैं यदि इसे निरंतर उदाहरणों के लिए निषिद्ध किया जाए।
एनालॉग फाइल

3
@golddove हाँ, और आप नहीं कर सकते। आपको नहीं करना चाहिए आपको हमेशा मूल्य का एक नया संस्करण बनाने या प्राप्त करने की आवश्यकता होती है, और आपके कार्यक्रम को जानबूझकर इस तरह अपनाने के लिए डिज़ाइन करने की आवश्यकता होती है। इस तरह के आकस्मिक उत्परिवर्तन को रोकने के लिए सुविधा मौजूद है। फिर, यह कार्यात्मक शैली प्रोग्रामिंग की मुख्य अवधारणा में से एक है ।
eonil

25

एक संरचना खेतों का एक एकत्रीकरण है; यदि एक विशेष संरचना का उदाहरण उत्परिवर्तनीय है, तो इसके क्षेत्र उत्परिवर्तनीय होंगे; यदि कोई उदाहरण अपरिवर्तनीय है, तो उसके क्षेत्र अपरिवर्तनीय होंगे। इस प्रकार एक संरचना प्रकार को इस संभावना के लिए तैयार किया जाना चाहिए कि किसी विशेष उदाहरण के क्षेत्र परस्पर या अपरिवर्तनीय हो सकते हैं।

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

इसे प्राप्त करने के लिए, स्विफ्ट संरचना के तरीकों को दो श्रेणियों में विभाजित करता है: वे जो अंतर्निहित संरचना को संशोधित करते हैं, और इस प्रकार केवल उत्परिवर्तनीय संरचना उदाहरणों पर लागू किए जा सकते हैं, और जो अंतर्निहित संरचना को संशोधित नहीं करते हैं और इस प्रकार दोनों उत्परिवर्तनीय और अपरिवर्तनीय उदाहरणों पर लागू होना चाहिए। । बाद का उपयोग संभवतः अधिक लगातार होता है, और इस प्रकार डिफ़ॉल्ट होता है।

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


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

19

सावधानी: आम आदमी की शर्तें आगे।

यह स्पष्टीकरण सबसे अधिक नटखट-किरकिरा कोड स्तर पर कठोरता से सही नहीं है। हालाँकि इसकी समीक्षा एक ऐसे व्यक्ति द्वारा की गई है जो वास्तव में स्विफ्ट पर काम करता है और उसने कहा कि यह एक बुनियादी स्पष्टीकरण के रूप में काफी अच्छा है।

इसलिए मैं "क्यों" के सवाल का सीधे और सीधे जवाब देने की कोशिश करना चाहता हूं ।

सटीक होने के लिए: हमें संरचनात्मक कार्यों को क्यों चिह्नित करना होगा, mutatingजब हम किसी भी संशोधित कीवर्ड के बिना संरचनात्मक मापदंडों को बदल सकते हैं?

तो, बड़ी तस्वीर, यह दर्शन के साथ बहुत कुछ करना है जो स्विफ्ट को तेज रखता है

आप इसे वास्तविक भौतिक पतों के प्रबंधन की समस्या की तरह सोच सकते हैं। जब आप अपना पता बदलते हैं, यदि आपके वर्तमान में बहुत सारे लोग हैं, तो आपको उन सभी को सूचित करना होगा जिन्हें आपने स्थानांतरित किया है। लेकिन अगर किसी के पास आपका वर्तमान पता नहीं है, तो आप जहां चाहें वहां जा सकते हैं, और किसी को भी जानने की जरूरत नहीं है।

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

यह भी यही कारण है कि स्विफ्ट-लोग सभी मूल्य प्रकार बनाम संदर्भ प्रकारों के बारे में सोच रहे हैं। स्वभाव से, संदर्भ प्रकार सभी जगह "संपर्क" को रैक करते हैं, और मूल्य प्रकारों को आमतौर पर एक जोड़े से अधिक की आवश्यकता नहीं होती है। मूल्य प्रकार "स्विफ्ट" -एर हैं।

तो वापस छोटी तस्वीर के लिए structs:। स्विफ्ट में संरचना एक बड़ी बात है क्योंकि वे ज्यादातर चीजें कर सकते हैं जो वस्तुएं कर सकती हैं, लेकिन वे मूल्य प्रकार हैं।

चलो एक कल्पना भौतिक पता सादृश्य जारी रखने के लिए misterStructहै कि में रहती है someObjectVille। सादृश्य यहाँ थोड़ा जीता है, लेकिन मुझे लगता है कि यह अभी भी उपयोगी है।

तो एक चर पर मॉडल को बदलने के लिए struct, मान लें कि misterStructहरे बाल हैं, और नीले बालों पर स्विच करने का आदेश मिलता है। सादृश्य हो जाता है, जैसे मैंने कहा, लेकिन ऐसा होता है कि misterStructपुराने बालों को बदलने के बजाय , पुराने व्यक्ति बाहर निकल जाता है और नीले बालों वाला एक नया व्यक्ति अंदर चला जाता है, और वह नया व्यक्ति खुद को कॉल करना शुरू कर देता है misterStruct। किसी को भी पते की अधिसूचना को बदलने की आवश्यकता नहीं है, लेकिन अगर कोई भी उस पते को देखता है, तो उन्हें नीले बालों वाला एक लड़का दिखाई देगा।

अब चलो जब आप किसी फ़ंक्शन को कॉल करते हैं तो मॉडल क्या होता है struct। इस मामले में, यह ऐसा है जैसे misterStructएक आदेश मिलता है changeYourHairBlue()। इसलिए डाकघर misterStruct"आपके बालों को नीले रंग में बदलने के लिए निर्देश देता है और मुझे बताता है कि आप कब काम कर रहे हैं।"

यदि वह पहले जैसी ही दिनचर्या का पालन कर रहा है, यदि वह वही कर रहा है, जब चर को सीधे बदल दिया गया था, तो वह क्या misterStructकरेगा अपने घर से बाहर निकलकर एक नए व्यक्ति को नीले बालों के साथ बुलाएगा। लेकिन यही समस्या है।

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

[वास्तव में इस साज़िश को कुछ भयावह रूप से जीतने के लिए, जो तकनीकी रूप से हरे-बालों वाले आदमी के साथ हुआ था, वह यह था कि बाहर जाने के बाद उसने तुरंत आत्महत्या कर ली थी। इसलिए वह किसी को भी सूचित नहीं कर सकता है कि कार्य पूरा हो गया है! ]

इस समस्या से बचने के लिए, केवल इस तरह के मामलों में , स्विफ्ट को उस पते पर सीधे घर जाना होगा और वास्तव में वर्तमान निवासी के बालों को बदलना होगा । यह एक नए आदमी में भेजने की तुलना में एक पूरी तरह से अलग प्रक्रिया है।

और यही कारण है कि स्विफ्ट हमें mutatingकीवर्ड का उपयोग करना चाहता है !

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

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

संक्षेप में, स्विफ्ट को तेज रहने में मदद करने के लिए, हम सभी को अपना हिस्सा करना चाहिए। :)

संपादित करें:

अरे यार / दुस्साहस जिसने मुझे नीचा दिखाया, मैंने अपना जवाब पूरी तरह से लिख दिया। यदि यह आपके साथ बेहतर बैठता है, तो क्या आप डाउनवोट को हटा देंगे?


1
यह ऐसा है <f-word-here> आईएनजी आश्चर्यजनक लिखा है! तो, समझने में इतना आसान है। मैंने इसके लिए इंटरनेट का परिमार्जन किया है और यहां जवाब है (वैसे भी, स्रोत कोड के माध्यम से जाने के बिना)। इसे लिखने के लिए समय निकालने के लिए बहुत बहुत धन्यवाद।
वैभव

1
मैं केवल यह पुष्टि करना चाहता हूं कि मैं इसे सही ढंग से समझता हूं: क्या हम यह कह सकते हैं कि, जब किसी संरचना उदाहरण की संपत्ति को सीधे स्विफ्ट में बदल दिया जाता है, तो संरचना का उदाहरण "समाप्त" हो जाता है और परिवर्तित संपत्ति के साथ एक नया उदाहरण "बनाया" जा रहा है परदे के पीछे? और जब हम उस उदाहरण की संपत्ति को बदलने के लिए उदाहरण के भीतर एक उत्परिवर्तन विधि का उपयोग करते हैं, तो यह समाप्ति और पुन: प्रारंभ करने की प्रक्रिया नहीं होती है?
टेड

@ मैं चाहता हूं कि मैं निश्चित रूप से उत्तर दे सकता हूं, लेकिन सबसे अच्छा मैं यह कह सकता हूं कि मैंने इस सादृश्य पिछले एक वास्तविक स्विफ्ट डेवलपर को दौड़ाया, और उन्होंने कहा कि "यह मूल रूप से सटीक है", जिसका अर्थ है कि एक तकनीकी अर्थ में यह अधिक है। लेकिन उस समझ के साथ - कि वहाँ यह सिर्फ इस से अधिक है - व्यापक अर्थों में, हाँ, यही इस सादृश्य कह रहा है।
ले मोट जूस

8

स्विफ्ट संरचना को स्थिरांक (के माध्यम से let) या चर (के माध्यम से var) के रूप में त्वरित किया जा सकता है

स्विफ्ट की Arrayसंरचना पर विचार करें (हाँ यह एक संरचना है)।

var petNames: [String] = ["Ruff", "Garfield", "Nemo"]
petNames.append("Harvey") // ["Ruff", "Garfield", "Nemo", "Harvey"]

let planetNames: [String] = ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"]
planetNames.append("Pluto") //Error, sorry Pluto. No can do

ग्रह नामों के साथ परिशिष्ट ने काम क्यों नहीं किया? क्योंकि परिशिष्ट mutatingखोजशब्द के साथ चिह्नित है । और जब से planetNamesप्रयोग करने की घोषणा की गई थी let, इस प्रकार चिह्नित सभी विधियां बंद सीमाएं हैं।

आपके उदाहरण में कंपाइलर बता सकता है कि आप किसी एक के बाहर एक या अधिक गुण निर्दिष्ट करके संरचना को संशोधित कर रहे हैं init। यदि आप अपना कोड बदलते हैं, तो आप उसे देखेंगे xऔर yहमेशा संरचना के बाहर पहुंच योग्य नहीं होंगे। letपहली पंक्ति पर ध्यान दें ।

let p = Point(x: 1, y: 2)
p.x = 3 //error
p.moveToX(5, andY: 5) //error

5

C ++ के साथ एक सादृश्य पर विचार करें। स्विफ्ट में एक संरचनात्मक विधि mutating/ नहीं- mutatingC ++ में एक विधि के अनुरूप है गैर- const/ constconstC ++ में चिह्नित एक विधि संरचना को उत्परिवर्तित नहीं कर सकती है।

आप एक संरचना के बाहर से एक संस्करण बदल सकते हैं, लेकिन आप इसे अपने तरीकों से नहीं बदल सकते।

सी ++ में, आप "संरचना के बाहर से एक संस्करण को बदल सकते हैं" - लेकिन केवल अगर आपके पास गैर- constसंरचना वाला चर है। यदि आपके पास एक constस्ट्रक्चर वैरिएबल है, तो आप एक var को असाइन नहीं कर सकते हैं, और आप एक गैर- constविधि भी नहीं कह सकते । इसी तरह, स्विफ्ट में, आप केवल एक संरचना की एक संपत्ति को बदल सकते हैं यदि संरचना चर स्थिर नहीं है। यदि आपके पास एक संरचना स्थिर है, तो आप एक संपत्ति को निर्दिष्ट नहीं कर सकते, और आप एक mutatingविधि भी नहीं कह सकते ।


1

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

आपकी संरचना के अंदर परिभाषित उत्परिवर्तन विधि स्वयं के प्रत्येक उदाहरण को संशोधित करने की अनुमति चाहती है जो भविष्य में कभी भी बनाई जाएगी। क्या होगा अगर उन उदाहरणों में से एक के साथ एक अपरिवर्तनीय स्थिरांक सौंपा जाए let? उह ओह। आपको खुद से बचाने के लिए (और संपादक और संकलक को यह बताने के लिए कि आप क्या करने की कोशिश कर रहे हैं), आप स्पष्ट होने के लिए मजबूर हैं जब आप इस तरह की शक्ति को एक उदाहरण विधि देना चाहते हैं।

इसके विपरीत, आपकी संरचना के बाहर से एक संपत्ति की स्थापना उस संरचना के ज्ञात उदाहरण पर काम कर रही है। यदि यह किसी स्थिरांक को सौंपा गया है, तो Xcode आपको उस पल के बारे में बताएगा जो आपने विधि कॉल में टाइप किया है।

यह उन चीजों में से एक है जो मैं स्विफ्ट के बारे में प्यार कर रहा हूं क्योंकि मैं इसे और अधिक उपयोग करना शुरू कर देता हूं - त्रुटियों के प्रति सचेत होने के साथ-साथ मैं उन्हें टाइप करता हूं। यकीन है कि अस्पष्ट जावास्क्रिप्ट जावास्क्रिप्ट कीड़े समस्या निवारण से बाहर धड़कता है!


1

स्विफ्ट: स्ट्रक्चर्स में म्यूटिंग फ़ंक्शन का उपयोग

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

struct City
{
  var population : Int 
  func changePopulation(newpopulation : Int)
  {
      population = newpopulation //error: cannot modify property "popultion"
  }
}
  var mycity = City(population : 1000)
  mycity.changePopulation(newpopulation : 2000)

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

हम इसे कैसे हल करेंगे? विकल्प क्या है?

म्यूटिंग कीवर्ड:

संरचना के अंदर उत्परिवर्तन के रूप में कार्य की घोषणा हमें संरचनाओं में गुणों को बदलने की अनुमति देती है। पंक्ति संख्या: 5, उपरोक्त कोड में इस तरह से परिवर्तन,

mutating changePopulation(newpopulation : Int)

अब हम विधि के दायरे में संपत्ति की आबादी के लिए न्यूपोपुलेशन के मूल्य को असाइन कर सकते हैं ।

ध्यान दें :

let mycity = City(1000)     
mycity.changePopulation(newpopulation : 2000)   //error: cannot modify property "popultion"

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

आपकी टिप्पणियों और विचारों को सुनना पसंद करेंगे… ..

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