अपरिचय के आसपास मेरा सिर हो रही है


13

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

जब मैं बयान करता हूं कि एक अपरिवर्तनीय वस्तु को नहीं बदला जा सकता है, तो मैं हैरान हूं क्योंकि मैं उदाहरण के लिए, निम्नलिखित कर सकता हूं:

NSString *myName = @"Bob";
myName = @"Mike";

वहाँ, मैंने अभी-अभी अपना नाम बदलकर, अपरिवर्तनीय प्रकार के NSString को बदल दिया है। मेरी समस्या यह है कि शब्द, "ऑब्जेक्ट" स्मृति में भौतिक वस्तु या अमूर्तता को संदर्भित कर सकता है, "myName।" पूर्व परिभाषा अपरिवर्तनीयता की अवधारणा पर लागू होती है।

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

क्या यह सही है, या मैं अभी भी जंगल में खो गया हूं?


13
आपका प्रकार कोई नहीं है NSString, यह एक " पॉइंटर टू और NSString" है, जो अपरिवर्तनीय नहीं है। मैं उद्देश्य सी के कुछ भी नहीं पता है, लेकिन मैं अपने उदाहरण है कि में अनुमान लगा रहा हूँ @"Mike"का एक नया उदाहरण पैदा कर रही है NSStringऔर करने के लिए यह बताए सूचक , myName। तो आपने उस ऑब्जेक्ट को नहीं बदला है जो myNameइंगित कर रहा था, बस वह क्या इंगित कर रहा था।
fwgx

2
@fwgx इसे एक उत्तर के रूप में रखो और तुम मेरे उत्थान को प्राप्त करोगे।
गुलशन

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

@ गुलशन ने, नीचे देखें ....
fwgx

अपरिवर्तनीयता को समझने के लिए, मैं एक प्रोग्रामिंग भाषा सीखने की सलाह देता हूं जो स्पष्ट रूप से बाइंडिंग (यानी वस्तुओं को नाम दे रही है) को परस्परता के साथ अलग करती है (यानी नाम को किसी अलग ऑब्जेक्ट पर पुन: असाइन करने की अनुमति देता है)। ML (किसी भी आड़ में: SML, Ocaml, F #) एक अच्छा उदाहरण है।
गिल्स एसओ- बुराई को रोकें '

जवाबों:


4

ऐसा लगता है कि आप सही दिशा में जा रहे हैं, लेकिन यह अभी तक नहीं मिला है। ये गलत है:

वहाँ, मैंने अभी-अभी अपना नाम बदलकर, अपरिवर्तनीय प्रकार के NSString को बदल दिया है। मेरी समस्या यह है कि शब्द, "ऑब्जेक्ट" स्मृति में भौतिक वस्तु या अमूर्तता को संदर्भित कर सकता है, "myName।"

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

तुम कहो:

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

ये गलत है। एक ऑब्जेक्ट पॉइंटर्स का मालिक नहीं है जो इसे इंगित करता है, और न ही किसी ऑब्जेक्ट के मेमोरी स्थान को नियंत्रित किया जाता है या अन्यथा किसी भी पॉइंटर्स द्वारा इसे प्रभावित किया जाता है।

तो, NSStringआपके उदाहरण में ( @"Bob"और @"Mike") दो वस्तुएं myNameचर से पूरी तरह से अलग हैं । वे एक दूसरे से पूरी तरह से अलग भी हैं। जब आप myNameइंगित करने के @"Mike"बजाय इंगित करने के लिए @"Bob"बदलते हैं, तो आप NSStringऑब्जेक्ट नहीं बदल रहे हैं।


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


17

आप शब्दों में खो जाते हैं। अपरिवर्तनशीलता का अर्थ है: जब तक आप चर को नहीं बदलते हैं, तब तक यह हमेशा समान मूल्य का "समाहित" होता है, इससे कोई फर्क नहीं पड़ता कि आप अन्य चर के साथ क्या करते हैं।

C में Counterexample (थोड़ा सा सरलीकृत, जो एक आर्किटेक्चर मानकर अनुमति देता है):

 char *a = "Hello World";
 char *b = a;
 b[0] = 'Y';

अब एक "" शामिल है "(यानी अंक पर) स्ट्रिंग" हैलो वर्ल्ड ", लेकिन यह" येल्लो वर्ल्ड "के बजाय है।

उन भाषाओं में जहां स्ट्रिंग अपरिवर्तनीय हैं, जैसे जावा और (EDIT: safe) C #, आप ऐसा नहीं कर सकते। बिल्कुल नहीं। इसका मतलब है कि कार्यक्रम का हर हिस्सा सुरक्षित रूप से स्ट्रिंग का एक संदर्भ रख सकता है और भरोसा कर सकता है कि इसकी सामग्री कभी नहीं बदलती है; अन्यथा, उन्हें केवल सुरक्षित पक्ष पर होने के लिए एक प्रति बनानी होगी।

लेकिन परिवर्तनशील अभी भी परिवर्तनशील है। आप इसे किसी अन्य ऑब्जेक्ट को इंगित कर सकते हैं। यह सिर्फ इतना है कि वस्तु ही आपकी पीठ के पीछे नहीं बदलेगी।


1
आप तकनीकी रूप से सी # में स्ट्रिंग सामग्री को संशोधित कर सकते हैं, आपको बस unsafeकोड का उपयोग करना होगा ।
आरोन

1
हारून: जानकारी के लिए धन्यवाद, आप सही हैं; हर किसी के लिए जो यह जानना आवश्यक है: msdn.microsoft.com/en-us/library/ms228599.aspx
user281377

10

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

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


3
मेरे पास कुछ पड़ोसी हैं जिन्हें मैं म्यूट करना पसंद करता था।
डेव नै

मुझे नहीं लगता कि आपको दूसरे अनुच्छेद में आपके उदाहरण की आवश्यकता है क्योंकि आपकी व्याख्या काफी अच्छी है। IMO उदाहरण केवल भ्रमित कर सकता है। हालाँकि chap के सवाल के एक संक्षिप्त जवाब के लिए +1।
पॉल मैकाबे

@ डावने: मैं चोरी की सजा के लिए माफी मांगता हूं। बिल्कुल इरादा नहीं था।
किलियन फोथ

6

एक चर एक वस्तु नहीं है। एक चर एक नाम है, जो एक वस्तु (या अधिक सामान्यतः एक मूल्य) को संदर्भित करता है।

उदाहरण के लिए "गोलकीपर" एक ऐसा नाम है जिसका उपयोग हम लक्ष्य की रक्षा के लिए जिम्मेदार वस्तु (व्यक्ति) को संदर्भित करने के लिए करते हैं। लेकिन अगर मैं उस व्यक्ति को दूसरे के द्वारा स्थानापन्न करता हूं (क्योंकि पहले वाला घायल हो गया है या नहीं), तो नए व्यक्ति को अब "गोलकीपर" के रूप में जाना जाता है।

असाइनमेंट स्टेटमेंट वह है जो वैरिएबल को म्यूटेबल बनाता है (कुछ भाषाएँ, जैसे हास्केल के पास यह नहीं है और वास्तव में अपरिवर्तनीय वेरिएबल का उपयोग करते हैं)। यह आपको एक नाम के अर्थ को फिर से परिभाषित करने की अनुमति देता है और इस तरह मूल्य को पुन: सौंपता है।

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

दोनों चर और मूल्य अपरिवर्तनीय (स्वतंत्र रूप से) हो सकते हैं। इस मामले में, यह ऐसी वस्तुएँ हैं जो अपरिवर्तनीय हैं। एक बार निर्माण करने के बाद NSString, आप इसे संशोधित नहीं कर सकते। आप इसे नाम दे सकते हैं और इसे पास कर सकते हैं, लेकिन यह वही रहेगा। इसके विपरीत, NSMutableStringनिर्माण के बाद बदला जा सकता है, उदाहरण के लिए setStringविधि को कॉल करके ।


Waggawooga तुलना प्यार!
माइकल के

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

4

मुझे लगता है कि आप खोए हुए महसूस करते हैं, क्योंकि आप दो अवधारणाओं का मिश्रण कर रहे हैं: वस्तु और चर नाम उस वस्तु से जुड़ा हुआ है।

अपरिवर्तनीय वस्तुओं को नहीं बदला जा सकता है। अवधि। हालांकि, चर नाम (प्रतीक) एक अपरिवर्तनीय वस्तु से बंधा हुआ है, किसी अन्य अपरिवर्तनीय वस्तु के लिए बाध्य होने के लिए संशोधित किया जा सकता है ।

दूसरे शब्दों में, आपने इन दो पंक्तियों में क्या किया था:

  1. मूल्य के साथ अपरिवर्तनीय स्ट्रिंग ऑब्जेक्ट बनाएं "बॉब"
  2. myNameउस वस्तु के प्रतीक को बांधें
  3. मूल्य "माइक" के साथ अपरिवर्तनीय स्ट्रिंग ऑब्जेक्ट बनाएं
  4. myNameउस वस्तु के प्रतीक को बांधें

2

आपका अपने प्रकार एक नहीं है NSStringकि यह एक "है, के लिए सूचक एक NSString" है, जो अपरिवर्तनीय नहीं है। मुझे उद्देश्य C का कुछ भी नहीं पता है, लेकिन मैं आपके उदाहरण में अनुमान लगा रहा हूं कि @"Mike"इसका एक नया उदाहरण बन रहा है NSStringऔर इसे पॉइंटर को असाइन करना है myName। तो आपने उस ऑब्जेक्ट को नहीं बदला है जो इंगित कर रहा myNameथा , बस वह क्या इंगित कर रहा था।


0

यहाँ एक परिवर्तनशील वस्तु का उदाहरण दिया charगया है: C में एक सरणी :

char str[10];

मैं बदल सकते हैं सामग्री की str(जब तक यह 10 अक्षरों से अधिक नहीं है के रूप में) मेरे दिल की सामग्री के लिए। इसके लिए C स्ट्रिंग लाइब्रेरी फ़ंक्शंस द्वारा एक स्ट्रिंग के रूप में पहचाना जाना चाहिए, एक अनुगामी 0 होना है, इसलिए यह लंबाई में 9 वर्णों तक तार पकड़ सकता है:

strcpy(str, "hello"); // str now contains the string "hello\0"
strcpy(str, "world"); // str now contains the string "world\0"

str[0] = 'W';         // str now contains "World\0"

und weiter

जावा में एक स्ट्रिंग ऑब्जेक्ट के साथ इसका विरोध करें:

String foo = "Hello";

स्ट्रिंग उदाहरण (वर्ण की स्मृति जिसमें वर्ण 'H', 'e', ​​'l', 'l', और 'o') को संशोधित नहीं किया जा सकता है; मैं उस स्ट्रिंग की किसी भी सामग्री को बदल नहीं सकता। जब आप कुछ ऐसा लिखते हैं

foo = foo + " World";

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

fooस्वयं स्ट्रिंग उदाहरण नहीं है; यह केवल उस उदाहरण (C या Obj-C में सूचक के समान) को संदर्भित करता है, इसलिए स्ट्रिंग जैसे प्रकारों को संदर्भ प्रकार कहा जाता है।

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