अपरिवर्तनीय वस्तुएं


173

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


stringकम से कम .NET में अपरिवर्तनीय है, और मुझे कई अन्य आधुनिक भाषाओं में भी लगता है।
डोमिनिक

4
यह इस बात पर निर्भर करता है कि भाषा में वास्तव में एक स्ट्रिंग क्या है - एर्गैंग 'स्ट्रिंग्स' सिर्फ एक अर्ट्स की एक सरणी है, और हैसेल "स्ट्रिंग्स" वर्णों के सरणियाँ हैं।
Chii

4
रूबी तार बाइट्स का एक परस्पर सरणी है। मुझे पागल कर देता है कि आप उन्हें जगह में बदल सकते हैं।
डैनियल स्पिवक

6
डैनियल - क्यों? क्या आप खुद को दुर्घटना से ऐसा कर पाते हैं?

5
@DanielSpiewak नट को बदलने के लिए समाधान जिससे आप स्ट्रिंग्स को बदल सकते हैं, सरल है: बस ऐसा न करें। पागल होने के लिए समाधान क्योंकि आप जगह में तारों को बदल नहीं सकते हैं वह सरल नहीं है।
काज

जवाबों:


162

खैर, इसके कुछ पहलू हैं।

  1. संदर्भ-पहचान के बिना उत्परिवर्तित वस्तुएं विषम समय में बग पैदा कर सकती हैं। उदाहरण के लिए, Personमूल्य आधारित equalsपद्धति के साथ सेम पर विचार करें :

    Map<Person, String> map = ...
    Person p = new Person();
    map.put(p, "Hey, there!");
    
    p.setName("Daniel");
    map.get(p);       // => null
    

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

  2. एक अन्य पहलू आपके कोड का तार्किक "तर्क" है। यह परिभाषित करने के लिए एक कठिन शब्द है, पठनीयता से प्रवाह के लिए सब कुछ शामिल है। आम तौर पर, आपको कोड के एक टुकड़े को देखने में सक्षम होना चाहिए और आसानी से समझ सकता है कि यह क्या करता है। लेकिन उससे भी ज्यादा महत्वपूर्ण यह है कि आप खुद को समझा सकें कि यह वही करता है जो वह सही ढंग से करता है । जब ऑब्जेक्ट अलग-अलग कोड "डोमेन" में स्वतंत्र रूप से बदल सकते हैं, तो कभी-कभी यह ट्रैक करना मुश्किल हो जाता है कि कहां और क्यों है (" दूरी पर डरावना कार्रवाई ")। यह अनुकरण करने के लिए एक अधिक कठिन अवधारणा है, लेकिन यह कुछ ऐसा है जो अक्सर बड़े, अधिक जटिल आर्किटेक्चर में सामना किया जाता है।

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

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

इसके साथ ही कहा, मैं शायद ही इस मामले में एक उत्साही हूं। जब कुछ अपरिवर्तनीय होता है तो कुछ समस्याएं बस अच्छी तरह से नहीं होती हैं। लेकिन मुझे लगता है कि आपको उस दिशा में अपने कोड के जितना संभव हो सके उतना धक्का देने की कोशिश करनी चाहिए, यह मानते हुए कि आप एक ऐसी भाषा का उपयोग कर रहे हैं, जो इसे एक टेनबल राय बनाती है (C / C ++ इसे बहुत कठिन बनाता है, जैसा कि जावा करता है) । संक्षेप में: फायदे कुछ हद तक आपकी समस्या पर निर्भर करते हैं, लेकिन मैं अपरिवर्तनीयता को प्राथमिकता देना चाहूंगा।


11
शानदार प्रतिक्रिया। हालांकि एक छोटा सा सवाल: क्या C ++ में अपरिवर्तनीयता के लिए अच्छा समर्थन नहीं है? क्या कांस्टेन्स-शुद्धता की सुविधा पर्याप्त नहीं है?
दिमित्री सी।

1
@DimitriC: C ++ में वास्तव में कुछ और मौलिक विशेषताएं हैं, सबसे विशेष रूप से भंडारण स्थानों के बीच एक बेहतर अंतर है जो कि उन लोगों से अनिर्धारित स्थिति को एनकैप्सुलेट करने के लिए माना जाता है जो ऑब्जेक्ट पहचान को अतिक्रमण करते हैं।
सुपरकाट

2
जावा प्रोग्रामिंग के मामले में जोशुआ बलोच अपनी प्रसिद्ध पुस्तक प्रभावी जावा (आइटम 15)
dMathieuD

27

अपरिवर्तनीय वस्तुएँ बनाम अपरिवर्तनीय संग्रह

उत्परिवर्तनीय बनाम अपरिवर्तनीय वस्तुओं पर बहस में एक बारीक बिंदु है संग्रह के लिए अपरिवर्तनीयता की अवधारणा का विस्तार करने की संभावना। एक अपरिवर्तनीय वस्तु एक ऐसी वस्तु है जो अक्सर डेटा की एकल तार्किक संरचना का प्रतिनिधित्व करती है (उदाहरण के लिए एक अपरिवर्तनीय स्ट्रिंग)। जब आपके पास एक अपरिवर्तनीय वस्तु का संदर्भ होता है, तो ऑब्जेक्ट की सामग्री नहीं बदलेगी।

अपरिवर्तनीय संग्रह एक संग्रह है जो कभी नहीं बदलता है।

जब मैं एक परिवर्तनशील संग्रह पर एक ऑपरेशन करता हूं, तो मैं संग्रह को जगह में बदल देता हूं, और संग्रह के संदर्भ वाली सभी संस्थाओं को परिवर्तन दिखाई देगा।

जब मैं एक अपरिवर्तनीय संग्रह पर एक ऑपरेशन करता हूं, तो एक संदर्भ नए संग्रह में वापस आ जाता है जो परिवर्तन को दर्शाता है। संग्रह के पिछले संस्करणों के संदर्भ वाली सभी संस्थाओं में परिवर्तन नहीं दिखेगा।

चतुर कार्यान्वयन को उस अपरिवर्तनीयता प्रदान करने के लिए पूरे संग्रह को कॉपी (क्लोन) करने की आवश्यकता नहीं है। सबसे सरल उदाहरण एक एकल लिंक की गई सूची और पुश / पॉप संचालन के रूप में लागू किया गया स्टैक है। आप नए संग्रह में पिछले संग्रह से सभी नोड्स का पुन: उपयोग कर सकते हैं, पुश के लिए केवल एक नोड जोड़ सकते हैं, और पॉप के लिए कोई नोड नहीं क्लोन कर सकते हैं। दूसरी ओर एक एकल लिंक की गई सूची पर पुश_टेल ऑपरेशन इतना सरल या कुशल नहीं है।

अपरिवर्तनीय बनाम म्यूटेबल चर / संदर्भ

कुछ कार्यात्मक भाषाएं केवल एक संदर्भ असाइनमेंट की अनुमति देते हुए, ऑब्जेक्ट संदर्भों के लिए अपरिवर्तनीयता की अवधारणा को लेती हैं।

  • एर्लैंग में यह सभी "चर" के लिए सच है। मैं केवल एक बार संदर्भ के लिए ऑब्जेक्ट असाइन कर सकता हूं। अगर मुझे किसी संग्रह पर काम करना था, तो मैं नए संग्रह को पुराने संदर्भ (चर नाम) को फिर से असाइन नहीं कर पाऊंगा।
  • स्काला इसे सभी संदर्भों के साथ भाषा में भी बनाता है जिसे var या val के साथ घोषित किया जा रहा है , vals केवल एकल असाइनमेंट है और एक कार्यात्मक शैली को बढ़ावा दे रहा है, लेकिन अधिक सी-लाइक या जावा जैसी प्रोग्राम संरचना की अनुमति देता है।
  • Var / val घोषणा की आवश्यकता है, जबकि कई पारंपरिक भाषाएं वैकल्पिक संशोधक का उपयोग करती हैं जैसे कि java में अंतिम और C में कास्ट

विकास बनाम प्रदर्शन में आसानी

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

मुख्य दोष प्रदर्शन है। यहाँ एक सरल परीक्षण पर लिखा गया है जो मैंने जावा में एक खिलौना समस्या में कुछ अपरिवर्तनीय बनाम उत्परिवर्तनीय वस्तुओं की तुलना में किया था

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


12

इस ब्लॉग पोस्ट की जाँच करें: http://www.yegor256.com/2014/06/09/objects-should-be-immutable.html । यह बताता है कि अपरिवर्तनीय वस्तुएँ उत्परिवर्तनीय से बेहतर क्यों हैं। संक्षेप में:

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

10

अपरिवर्तनीय वस्तुएँ एक बहुत शक्तिशाली अवधारणा हैं। वे सभी ग्राहकों के लिए वस्तुओं / चर को सुसंगत रखने की कोशिश का बहुत बोझ उठाते हैं।

आप उनका उपयोग निम्न स्तर, गैर-बहुरूपी वस्तुओं - जैसे कि CPoint वर्ग - के लिए कर सकते हैं, का उपयोग ज्यादातर मूल्य शब्दार्थ के साथ किया जाता है।

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

सबसे बड़ा लाभ: अपरिवर्तनीयता + ऑब्जेक्ट शब्दार्थ + स्मार्ट पॉइंटर्स ऑब्जेक्ट के स्वामित्व को एक गैर-मुद्दा बनाते हैं, ऑब्जेक्ट के सभी ग्राहकों की डिफ़ॉल्ट रूप से अपनी निजी प्रति होती है। स्पष्ट रूप से इसका मतलब यह भी है कि संगामिति की उपस्थिति में निर्धारक व्यवहार।

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

इसलिए अपरिवर्तनीय वस्तुएं निश्चित रूप से ऑब्जेक्ट-ओरिएंटेड डिज़ाइन के बारे में सोचने का मेरा प्राथमिक तरीका है, लेकिन वे हठधर्मिता नहीं हैं। वे वस्तुओं के ग्राहकों के लिए बहुत सी समस्याओं को हल करते हैं, लेकिन कई को भी लागू करते हैं, खासकर कार्यान्वयनकर्ताओं के लिए।


मुझे लगता है कि मुझे सबसे बड़ा फायदा के लिए धारा 4 को गलत समझा गया है: अपरिवर्तनीयता + वस्तु शब्दार्थ + स्मार्ट पॉइंटर्स एक "मूट" बिंदु के स्वामित्व वाले ऑब्जेक्ट को प्रस्तुत करता है। तो यह बहस का मुद्दा है? मुझे लगता है कि आप गलत तरीके से "मूट" का उपयोग कर रहे हैं ... अगले वाक्य के रूप में देख रहा है कि वस्तु ने "निर्धारक व्यवहार" को इसके "म्यूट" (डिबेटेबल) व्यवहार से निहित किया है।
बेंजामिन

आप सही कह रहे हैं, मैंने गलत तरीके से 'मूट' का इस्तेमाल किया। इस पर विचार करें :)
QBziZ

6

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


आप सुझाव दे रहे हैं कि धागे क्वांटम रूप से उलझ गए हैं? यह काफी खिंचाव है :) थ्रेड्स वास्तव में हैं, अगर आप इसके बारे में सोचते हैं, तो उलझने के करीब। एक परिवर्तन जो एक धागा दूसरे को प्रभावित करता है। +1
ndrewxie

4

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

मुझे नहीं लगता कि कोई स्पष्ट जवाब है, जिसमें सभी स्थितियों के लिए बेहतर है। उन दोनों के पास अपने स्थान हैं।


1

यदि एक वर्ग प्रकार उत्परिवर्तनीय है, तो उस वर्ग प्रकार के एक चर में कई अर्थ हो सकते हैं। उदाहरण के लिए, मान लें कि किसी ऑब्जेक्ट fooमें एक फ़ील्ड है int[] arr, और यह int[3]संख्या {5, 7, 9} को पकड़े हुए है। भले ही क्षेत्र का प्रकार ज्ञात हो, कम से कम चार अलग-अलग चीजें हैं जो यह प्रतिनिधित्व कर सकती हैं:

  • एक संभावित रूप से साझा संदर्भ, के सभी जिसका धारकों परवाह ही है कि यह मान समाहित 5, 7, और 9. यदि fooआवश्यकताओं arrविभिन्न मूल्यों को संपुटित करने के लिए, यह एक अलग सरणी कि वांछित मान के साथ बदलना होगा। यदि कोई इसकी एक प्रति बनाना चाहता है foo, तो कोई भी प्रति या arr1,9,3} मानों को धारण करने वाली एक नई सरणी या संदर्भ के लिए प्रति दे सकता है , जो भी अधिक सुविधाजनक हो।

  • ब्रह्मांड में कहीं भी एकमात्र संदर्भ, एक ऐसे सरणी में जो मान 5, 7 और 9 को सेट करता है। तीन भंडारण स्थानों का सेट जो इस समय मान 5, 7, और 9 को धारण करता है; यदि fooवह 5, 8 और 9 मानों को इनकैप्सुलेट करना चाहता है, तो यह या तो उस सरणी में दूसरा आइटम बदल सकता है या मान 5, 8, और 9 मान रखने वाला एक नया सरणी बना सकता है और पुराने को छोड़ सकता है। ध्यान दें कि यदि कोई इसकी प्रतिलिपि बनाना चाहता है foo, तो प्रतिलिपि को ब्रह्मांड में कहीं भी उस सरणी के एकमात्र संदर्भ के रूप में बने रहने के arrलिए एक नए सरणी के संदर्भ में प्रतिस्थापित करना चाहिए foo.arr

  • एक सरणी का संदर्भ जो किसी अन्य वस्तु के स्वामित्व में है जिसने इसे fooकिसी कारण से उजागर किया है (उदाहरण के लिए शायद यह fooवहां कुछ डेटा संग्रहीत करना चाहता है)। इस परिदृश्य में, arrसरणी की सामग्री को संक्षिप्त नहीं करता है, बल्कि इसकी पहचान है । क्योंकि arrएक नए सरणी के संदर्भ के साथ प्रतिस्थापित करने से इसका अर्थ पूरी तरह से बदल जाएगा, fooउसी सरणी के लिए एक प्रति चाहिए।

  • एक सरणी का संदर्भ fooएकमात्र स्वामी है, लेकिन जिसके संदर्भ को किसी अन्य कारण से किसी अन्य कारण से रखा जाता है (जैसे कि वह अन्य वस्तु को वहां डेटा संग्रहीत करने के लिए चाहता है - पिछले मामले का फ़्लिपसाइड)। इस परिदृश्य में, arrसरणी और उसकी सामग्री की पहचान दोनों को एन्क्रिप्ट करता है। arrएक नए सरणी के संदर्भ के साथ प्रतिस्थापित करने से इसका अर्थ पूरी तरह से बदल जाएगा, लेकिन क्लोन का arrसंदर्भ होने पर foo.arrयह धारणा का उल्लंघन होगा कि fooएकमात्र मालिक है। इस प्रकार नकल करने का कोई तरीका नहीं है foo

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


1

परस्पर उदाहरण संदर्भ द्वारा पारित किया जाता है।

अपरिवर्तनीय उदाहरण मूल्य द्वारा पारित किया जाता है।

सार उदाहरण। मान लीजिए कि मेरे HDD में txtfile नामक एक फ़ाइल मौजूद है । अब, जब आप मुझसे txtfile पूछते हैं , तो मैं इसे दो तरीकों से वापस कर सकता हूं:

  1. आप को txtfile और pas शॉर्टकट का शॉर्टकट बनाएँ , या
  2. Txtfile और pas copy के लिए एक प्रति अपने पास रखें।

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

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


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

0

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


0

अपरिवर्तनीय साधनों को बदला नहीं जा सकता है, और परिवर्तनशील साधनों को आप बदल सकते हैं।

जावा में वस्तुएं आदिम से भिन्न हैं। प्रिमिटिव प्रकार (बूलियन, इंट, आदि) में निर्मित होते हैं और ऑब्जेक्ट (क्लासेस) उपयोगकर्ता द्वारा बनाए गए प्रकार होते हैं।

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

बहुत से लोग सोचते हैं कि प्राइमेटिव और ऑब्जेक्ट वैरिएबल वाले उनमें से एक अंतिम संशोधक अपरिवर्तनीय है, हालांकि, यह बिल्कुल सच नहीं है। तो अंतिम लगभग चर के लिए अपरिवर्तनीय का मतलब नहीं है। उदाहरण यहाँ देखें
http://www.siteconsortium.com/h/D0000F.php


0

Immutable object- एक वस्तु स्थिति है, जिसे निर्माण के बाद नहीं बदला जा सकता है। ऑब्जेक्ट अपरिवर्तनीय है जब सभी फ़ील्ड्स अपरिवर्तनीय हैं

सुरक्षित धागा

अपरिवर्तनीय वस्तु का मुख्य लाभ यह है कि यह स्वाभाविक रूप से समवर्ती पर्यावरण के लिए है। कंसीडर में सबसे बड़ी समस्या है shared resourceजिसे किसी भी थ्रेड को बदला जा सकता है। लेकिन अगर कोई वस्तु अपरिवर्तनीय है, read-onlyजो कि थ्रेड सेफ ऑपरेशन है। एक मूल अपरिवर्तनीय वस्तु का कोई भी संशोधन एक प्रति लौटाता है

दुष्प्रभाव मुक्त

एक डेवलपर के रूप में आप पूरी तरह से सुनिश्चित हैं कि अपरिवर्तनीय वस्तु की स्थिति को किसी भी स्थान से नहीं बदला जा सकता है (उद्देश्य या नहीं)

संकलन का अनुकूलन

प्रदर्शन सुधारना

हानि:

एक उत्परिवर्तित वस्तु को बदलने की तुलना में ऑब्जेक्ट की प्रतिलिपि बनाना अधिक भारी ऑपरेशन है, यही कारण है कि इसमें कुछ प्रदर्शन पदचिह्न हैं

एक ऐसी immutableवस्तु बनाने के लिए जिसका आपको उपयोग करना चाहिए:

  1. भाषा का स्तर। प्रत्येक भाषा में आपकी सहायता के लिए उपकरण होते हैं। उदाहरण के लिए जावा है finalऔर primitives, स्विफ्ट है letऔर struct[हमारे बारे में] । भाषा एक प्रकार के चर को परिभाषित करती है। उदाहरण के लिए जावा में टाइप primitiveऔर reference, स्विफ्ट है valueऔर referenceटाइप [अबाउट] । अपरिवर्तनीय वस्तुओं के लिए अधिक सुविधाजनक primitivesऔर valueप्रकार है जो डिफ़ॉल्ट रूप से प्रतिलिपि बनाते हैं। के रूप में के लिए referenceप्रकार और अधिक कठिन है, लेकिन संभव (क्योंकि आप वस्तु के राज्य को इससे बाहर बदलने में सक्षम हैं)। उदाहरण के लिए आप cloneएक डेवलपर स्तर पर पैटर्न का उपयोग कर सकते हैं

  2. डेवलपर स्तर। एक डेवलपर के रूप में आपको बदलती स्थिति के लिए एक इंटरफ़ेस प्रदान नहीं करना चाहिए

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