Scala Language
अपरिवर्तनीय शैली में डेटा के साथ काम करना
खोज…
टिप्पणियों
मूल्य और चर नाम कम ऊंट मामले में होना चाहिए
लगातार ऊंट मामले में नाम होना चाहिए। यही है, यदि सदस्य अंतिम है, अपरिवर्तनीय है और यह एक पैकेज ऑब्जेक्ट या ऑब्जेक्ट से संबंधित है, तो इसे एक स्थिरांक माना जा सकता है
विधि, मान और चर नाम कम ऊंट मामले में होना चाहिए
स्रोत: http://docs.scala-lang.org/style/naming-conventions.html
यह संकलन:
val (a,b) = (1,2)
// a: Int = 1
// b: Int = 2
लेकिन यह नहीं है:
val (A,B) = (1,2)
// error: not found: value A
// error: not found: value B
यह सिर्फ वैल बनाम var नहीं है
val और var
scala> val a = 123
a: Int = 123
scala> a = 456
<console>:8: error: reassignment to val
a = 456
scala> var b = 123
b: Int = 123
scala> b = 321
b: Int = 321
-
valसंदर्भ अपरिवर्तनीय हैं:Javaमेंfinalचर की तरह, एक बार जब इसे आरंभ किया गया तो आप इसे बदल नहीं सकते हैं -
varमें एक साधारण परिवर्तनशील घोषणा के रूप मेंvarसंदर्भ पुन: संकेत हैं
अपरिवर्तनीय और पारस्परिक संग्रह
val mut = scala.collection.mutable.Map.empty[String, Int]
mut += ("123" -> 123)
mut += ("456" -> 456)
mut += ("789" -> 789)
val imm = scala.collection.immutable.Map.empty[String, Int]
imm + ("123" -> 123)
imm + ("456" -> 456)
imm + ("789" -> 789)
scala> mut
Map(123 -> 123, 456 -> 456, 789 -> 789)
scala> imm
Map()
scala> imm + ("123" -> 123) + ("456" -> 456) + ("789" -> 789)
Map(123 -> 123, 456 -> 456, 789 -> 789)
स्काला मानक पुस्तकालय अपरिवर्तनीय और परिवर्तनशील डेटा संरचनाएं प्रदान करता है, न कि इसका संदर्भ। हर बार एक अपरिवर्तनीय डेटा संरचना को "संशोधित" किया जाता है, मूल संग्रह को जगह में संशोधित करने के बजाय एक नया उदाहरण निर्मित होता है। संग्रह का प्रत्येक उदाहरण एक अन्य उदाहरण के साथ महत्वपूर्ण संरचना साझा कर सकता है।
म्युचुअल एंड इम्यूटेबल कलेक्शन (आधिकारिक स्काला डॉक्यूमेंटेशन)
लेकिन मैं इस मामले में अपरिवर्तनीयता का उपयोग नहीं कर सकता!
आइए एक उदाहरण के रूप में कार्य करते हैं जो 2 Map लेता है और ma और mb में हर तत्व से युक्त Map लौटाता है:
def merge2Maps(ma: Map[String, Int], mb: Map[String, Int]): Map[String, Int]
पहला प्रयास मानचित्रों में से एक for ((k, v) <- map) के तत्वों के माध्यम से पुनरावृत्त हो सकता है और किसी तरह विलय किए गए नक्शे को वापस कर सकता है।
def merge2Maps(ma: ..., mb: ...): Map[String, Int] = {
for ((k, v) <- mb) {
???
}
}
एक उत्परिवर्तन के बाहर है कि: यह बहुत पहला कदम तुरंत एक विवश जोड़ने for अब जरूरत है। डे-शुगरिंग के for यह अधिक स्पष्ट है:
// this:
for ((k, v) <- map) { ??? }
// is equivalent to:
map.foreach { case (k, v) => ??? }
"हमें म्यूट क्यों करना है?"
foreach साइड-इफेक्ट्स पर निर्भर करता है। हर बार जब हम एक के भीतर हो के लिए कुछ करना चाहता हूँ foreach हम करने के लिए "पक्ष प्रभाव कुछ" की जरूरत है, इस मामले में हम एक चर उत्परिवर्तित सकता var result या हम एक परिवर्तनशील डेटा संरचना का उपयोग कर सकते हैं।
result मानचित्र बनाना और भरना
मान scala.collection.immutable.Map हैं कि ma और mb scala.collection.immutable.Map , हम result को ma से बना सकते हैं:
val result = mutable.Map() ++ ma
फिर अपने तत्वों को जोड़ने के लिए mb माध्यम से पुनरावृत्ति करें और यदि ma पर वर्तमान तत्व की key पहले से मौजूद है, तो इसे mb साथ ओवरराइड करें।
mb.foreach { case (k, v) => result += (k -> v) }
परस्पर कार्यान्वयन
अब तक बहुत अच्छा, हमें "म्यूटेबल संग्रह का उपयोग करना पड़ा" और एक सही कार्यान्वयन हो सकता है:
def merge2Maps(ma: Map[String, Int], mb: Map[String, Int]): Map[String, Int] = {
val result = scala.collection.mutable.Map() ++ ma
mb.foreach { case (k, v) => result += (k -> v) }
result.toMap // to get back an immutable Map
}
जैसा सोचा था:
scala> merge2Maps(Map("a" -> 11, "b" -> 12), Map("b" -> 22, "c" -> 23))
Map(a -> 11, b -> 22, c -> 23)
बचाव के लिए तह
हम कैसे से छुटकारा पा सकते foreach इस परिदृश्य में? यदि हम सभी को क्या करना है तो मूल रूप से संग्रह तत्वों पर पुनरावृति होती है और विकल्प पर परिणाम जमा करते समय एक फ़ंक्शन लागू होता है। उपयोग किया जा सकता है .foldLeft :
def merge2Maps(ma: Map[String, Int], mb: Map[String, Int]): Map[String, Int] = {
mb.foldLeft(ma) { case (result, (k, v)) => result + (k -> v) }
// or more concisely mb.foldLeft(ma) { _ + _ }
}
इस मामले में हमारा "परिणाम" ma से शुरू होने वाला संचित मूल्य है, .foldLeft का zero ।
इंटरमीडिएट का रिजल्ट
स्पष्ट रूप से यह अपरिवर्तनीय समाधान तह करते समय कई Map उदाहरणों का निर्माण और विनाश कर रहा है, लेकिन यह ध्यान देने योग्य है कि वे उदाहरण संचित Map का पूर्ण क्लोन नहीं हैं, बल्कि मौजूदा उदाहरण के साथ महत्वपूर्ण संरचना (डेटा) साझा कर रहे हैं।
आसान तर्क
यदि यह .foldLeft दृष्टिकोण के रूप में अधिक घोषणात्मक है, तो सिमेंटिक के बारे में तर्क करना आसान है। अपरिवर्तनीय डेटा संरचनाओं का उपयोग करने से हमारे क्रियान्वयन को आसान बनाने में मदद मिल सकती है।