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
दृष्टिकोण के रूप में अधिक घोषणात्मक है, तो सिमेंटिक के बारे में तर्क करना आसान है। अपरिवर्तनीय डेटा संरचनाओं का उपयोग करने से हमारे क्रियान्वयन को आसान बनाने में मदद मिल सकती है।