2010-04-09 8 views
43

यह इस सवाल के पीछे है: Why can't strings be mutable in Java and .NET?मैट ने रूबी में डिफ़ॉल्ट रूप से स्ट्रिंग्स को म्यूटेबल बनाने का विकल्प क्यों चुना?

इस चुनाव रूबी में बनाया गया था की वजह से ही परिचालन (संलग्न कर देता है और इस तरह के) परिवर्तनशील तारों पर कुशल हैं, या कुछ अन्य कारण था?

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

+0

नोट: मुझे रूबी के बारे में बहुत कम पता है। लेकिन मुझे भाषा डिजाइन में दिलचस्पी है। –

+4

आप Matz क्यों नहीं पूछते हैं? –

+3

@ सैम: हाहा, अच्छा बिंदु हम उससे बेहतर जवाब दे सकते हैं। मुझे उम्मीद है कि उसने कहीं इसके बारे में लिखा है और कोई मुझे इसके बारे में बता सकता है या सारांशित कर सकता है। –

उत्तर

32

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

रूबी में कई विनाशकारी विधियां भी हैं जैसे String#upcase! जो तारों पर विचलित होने पर भरोसा करते हैं।

एक अन्य संभावित कारण यह है कि रूबी पर्ल से प्रेरित है, और पर्ल उत्परिवर्तनीय तारों का उपयोग होता है।

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

+0

ठीक है। लेकिन स्ट्रिंग्स डिफ़ॉल्ट रूप से mutable क्यों हैं? मैंने प्रश्न संपादित किया है और "डिफ़ॉल्ट रूप से" जोड़ा है। –

+2

उस पर '.frozen' को कॉल करके एक स्ट्रिंग अपरिवर्तनीय बनाना संभव है, लेकिन आप वास्तव में एक अपरिवर्तनीय स्ट्रिंग को व्यवहार्य नहीं बना सकते - यह सिद्धांत का उल्लंघन करेगा। उदाहरण के लिए, यदि मैं किसी फ़ंक्शन में एक अपरिवर्तनीय स्ट्रिंग पास करता हूं, तो मैं फ़ंक्शन को इसे व्यवहार्य बनाने और इसे बदलने शुरू करने की अपेक्षा नहीं करता। – rjh

+0

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

4

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

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

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

  3. पायथन में, ऐसा लगता है कि सम्मिलन बिंदु से पहले और बाद में सबस्ट्रिंग को पकड़ने के लिए सबसे आसान तरीका है, फिर उन्हें सम्मिलित स्ट्रिंग के चारों ओर संयोजित करें। मुझे लगता है कि वे आसानी से मानक लाइब्रेरी में एक विधि जोड़ सकते हैं जो एक नई स्ट्रिंग को सम्मिलित करता है और देता है।हालांकि, अगर विधि को insert कहा जाता है, तो शुरुआती सोच सकते हैं कि यह स्ट्रिंग को बदल देता है; वर्णनात्मक होने के लिए इसे new_with_inserted या उस तरह की कुछ अजीब कहा जाना चाहिए। रोजमर्रा के उपयोग में, "डालने" का अर्थ है कि आप डालने वाली चीजों की सामग्री को बदलते हैं (उदाहरण के लिए मेलबॉक्स में लिफाफा डालने से मेलबॉक्स की सामग्री बदलती है)। फिर, यह सवाल उठता है, "मैं अपना डेटा स्टोर क्यों नहीं बदल सकता?"

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

संबंधित मुद्दे