माफ़ करना शीर्षक के लिए खेद है - अगर मैं संक्षिप्त शीर्षक के साथ आ सकता हूं, तो मुझे सवाल पूछने की ज़रूरत नहीं है।
मान लीजिए कि मेरे पास एक अपरिवर्तनीय सूची प्रकार है। इसमें एक ऑपरेशन होता है Foo(x)जो अंत में एक अतिरिक्त तत्व के रूप में निर्दिष्ट तर्क के साथ एक नई अपरिवर्तनीय सूची देता है। तो "हैलो", "अपरिवर्तनीय", "दुनिया" के मानों के साथ तार की एक सूची बनाने के लिए आप लिख सकते हैं:
var empty = new ImmutableList<string>();
var list1 = empty.Foo("Hello");
var list2 = list1.Foo("immutable");
var list3 = list2.Foo("word");
(यह C # कोड है, और मुझे C # सुझाव में सबसे अधिक दिलचस्पी है अगर आपको लगता है कि भाषा महत्वपूर्ण है। यह मूल रूप से भाषा का सवाल नहीं है, लेकिन भाषा के मुहावरे महत्वपूर्ण हो सकते हैं।)
महत्वपूर्ण बात यह है कि मौजूदा सूचियों में कोई बदलाव नहीं किया गया है Foo- इसलिए empty.Countअभी भी 0 वापस आएंगे।
अंतिम परिणाम प्राप्त करने का एक और (अधिक मुहावरेदार) तरीका होगा:
var list = new ImmutableList<string>().Foo("Hello")
.Foo("immutable")
.Foo("word");
मेरा सवाल है: फू के लिए सबसे अच्छा नाम क्या है?
EDIT 3 : जैसा कि मैंने बाद में खुलासा किया है, प्रकार का नाम वास्तव में नहीं हो सकता है ImmutableList<T>, जिससे स्थिति स्पष्ट हो जाती है। इसके बजाय कल्पना कीजिए कि यह है TestSuiteऔर यह अपरिवर्तनीय है क्योंकि यह जिस ढांचे का हिस्सा है, उसका पूरा हिस्सा अपरिवर्तनीय है ...
(संपादन 3 का अंत)
मेरे पास अब तक आए विकल्प:
Add.NET में सामान्य, लेकिन इसका अर्थ है मूल सूची का म्यूटेशनCons: मेरा मानना है कि यह कार्यात्मक भाषाओं में सामान्य नाम है, लेकिन ऐसी भाषाओं में अनुभव के बिना उन लोगों के लिए अर्थहीन हैPlus: मेरा पसंदीदा अब तक, यह मेरे लिए उत्परिवर्तन नहीं करता है । जाहिरा तौर पर यह हास्केल में भी उपयोग किया जाता है लेकिन थोड़ी अलग अपेक्षाओं के साथ (एक हास्केल प्रोग्रामर इसे दूसरी सूची में एक मान जोड़ने के बजाय दो सूचियों को एक साथ जोड़ने की उम्मीद कर सकता है)।With: कुछ अन्य अपरिवर्तनीय सम्मेलनों के साथ संगत है, लेकिन यह IMO के लिए समान "समानता" नहीं है।And: बहुत वर्णनात्मक नहीं है।- ऑपरेटर अधिभार + के लिए: मुझे वास्तव में यह पसंद नहीं है; मुझे आमतौर पर लगता है कि ऑपरेटरों को केवल निचले स्तर के प्रकारों पर लागू किया जाना चाहिए। मैं हालांकि राजी होने को तैयार हूँ!
जो मापदंड मैं चुनने के लिए उपयोग कर रहा हूं वे हैं:
- विधि कॉल के परिणाम का सही प्रभाव देता है (अर्थात यह एक अतिरिक्त तत्व के साथ मूल सूची है)
- इसे यथासंभव स्पष्ट करता है कि यह मौजूदा सूची को म्यूट नहीं करता है
- उचित लगता है जब ऊपर दूसरे उदाहरण के रूप में एक साथ जंजीर
कृपया अधिक जानकारी के लिए पूछें कि क्या मैं खुद को पर्याप्त स्पष्ट नहीं कर रहा हूं ...
संपादित करें 1: यहाँ मेरा तर्क पसंद Plusकरने के लिए है Add। कोड की इन दो पंक्तियों पर विचार करें:
list.Add(foo);
list.Plus(foo);
(और यह मेरी नजर में है एक व्यक्तिगत बात) उत्तरार्द्ध स्पष्ट रूप से गाड़ी है - यह लेखन की तरह है "x + 5," अपने आप ही एक बयान के रूप में। पहली पंक्ति ऐसी लगती है जैसे कि यह ठीक है, जब तक आपको याद न हो कि यह अपरिवर्तनीय है। वास्तव में, जिस तरह से अपने आप से अधिक ऑपरेटर अपने ऑपरेंड को म्यूट नहीं करता है, Plusवह मेरे पसंदीदा होने का एक और कारण है। ऑपरेटर ओवरलोडिंग की थोड़ी सी भी बीमारी के बिना, यह अभी भी एक ही अर्थ देता है, जिसमें शामिल हैं (मेरे लिए) ऑपरेंड (या इस मामले में विधि का लक्ष्य) को बदलना नहीं।
एडिट 2: ऐड पसंद न करने के कारण।
विभिन्न उत्तर प्रभावी रूप से हैं: "ऐड के साथ जाएं। यही DateTimeहै, और Stringऐसे Replaceतरीके आदि हैं जो अपरिवर्तनीयता को स्पष्ट नहीं करते हैं।" मैं सहमत हूँ - यहाँ पूर्वता है। हालांकि, मैं बहुत देखा है की लोगों को कॉल DateTime.Addया String.Replaceऔर उत्परिवर्तन की उम्मीद । न्यूज़ग्रुप प्रश्नों का भार होता है (और शायद एसओ अगर मैं चारों ओर खोदता हूं) तो उत्तर दिया जाता है कि "आप वापसी मूल्य की अनदेखी String.Replaceकर रहे हैं; तार अपरिवर्तनीय हैं, एक नया स्ट्रिंग वापस आ जाता है।"
अब, मुझे प्रश्न के लिए एक सूक्ष्मता प्रकट करनी चाहिए - प्रकार वास्तव में एक अपरिवर्तनीय सूची नहीं हो सकती है , लेकिन एक अलग अपरिवर्तनीय प्रकार है। विशेष रूप से, मैं एक बेंचमार्किंग ढांचे पर काम कर रहा हूं, जहां आप एक सूट में परीक्षण जोड़ते हैं, और यह एक नया सूट बनाता है। यह स्पष्ट हो सकता है कि:
var list = new ImmutableList<string>();
list.Add("foo");
कुछ भी पूरा करने के लिए नहीं जा रहा है, लेकिन जब आप इसे बदलते हैं, तो यह बहुत आसान हो जाता है:
var suite = new TestSuite<string, int>();
suite.Add(x => x.Length);
ऐसा लग रहा है कि यह ठीक होना चाहिए। जबकि यह, मेरे लिए, गलती को स्पष्ट करता है:
var suite = new TestSuite<string, int>();
suite.Plus(x => x.Length);
वह सिर्फ भीख माँग रहा है:
var suite = new TestSuite<string, int>().Plus(x => x.Length);
आदर्श रूप में, मैं चाहूंगा कि मेरे उपयोगकर्ताओं को यह न बताया जाए कि टेस्ट सूट अपरिवर्तनीय है। मैं उन्हें सफलता के गर्त में गिराना चाहता हूं। यह संभव नहीं हो सकता है, लेकिन मैं कोशिश करना चाहूंगा।
मैं केवल एक अपरिवर्तनीय सूची प्रकार के बारे में बात करके मूल प्रश्न को सरल बनाने के लिए माफी माँगता हूँ। सभी संग्रह स्व-वर्णनात्मक के रूप में काफी नहीं हैं ImmutableList<T>:)