/ / एरे और सूची के बीच स्केला टाइप पैटर्न पैटर्न का अंतर - स्केला, पैटर्न-मिलान, टाइप-इरेज़र

ऐरे और सूची के बीच स्कैला टाइप पैटर्न पैटर्न का अंतर - स्कैला, पैटर्न-मिलान, टाइप-एरर

मेरे पास निम्नलिखित कथन हैं।

val a: Any = Array("1", "2", "3")
a match {
case p: Array[Int] => println("int")
case l: Array[String] => println("string")
}

val b: Any = List(1, 2, 3)
b match {
case l: List[String] => println("string")
case p: List[Int] => println("int")
}

ऐरे के बारे में पहला ब्लॉक चेतावनी और आउटपुट "स्ट्रिंग" के बिना संकलित करता है, जबकि सूची के बारे में दूसरा एक प्रकार इरेज़ से संबंधित चेतावनियों के साथ संकलन करता है और "स्ट्रिंग" के रूप में अच्छी तरह से आउटपुट करता है।

मुझे JVM में टाइप इरेज़र के बारे में कुछ पता है। रनटाइम के दौरान, JVM वास्तव में एक कंटेनर के सामान्य प्रकार (जैसे सूची) को नहीं जान सकता है। लेकिन अर्रे रनटाइम में टाइप एरेस्योर से क्यों बच सकते हैं और सही प्रकार से मेल खाते हैं?

मैंने स्कैला सोर्स कोड से जवाब खोजने की कोशिश की। केवल एक चीज मुझे मिली है कि एरे क्लासटैग का उपयोग करता है लेकिन सूची नहीं करता है।

मुझे पसंद है कि क्लासटैग कैसे काम करता है। क्या क्लासटैग टाइप इरेज़र का वर्कअराउंड है? और लिस्ट हेवन जैसे कंटेनरों को टाइप एग्योर से बचने के लिए क्लासटैग के साथ क्यों लागू किया गया है।

उत्तर:

उत्तर № 1 के लिए 4

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

लेकिन सरणियाँ जावा में विशेष मामला है, वे प्रकार की जानकारी रखते हैं। तो स्कैला एरेज़ करते हैं। यह जरूरी है कि एरेज़ के अंदर मेमोरी कुशल अनबॉक्स्ड वैल्यूज़ रखें।

आपको बस यह मान लेना चाहिए कि रनटाइम के दौरान सभी प्रकार की जानकारी खो जाती है। इसलिए उनके खिलाफ मिलान करने के लिए कुछ टैग का उपयोग करें।


ClassTags सरणी रैपिंग से संबंधित नहीं हैं। सभी प्रकार की जानकारी JVM द्वारा ही प्रदान की जाती है।

AnyRef का उपयोग करने के लिए जावा में कस्टम प्रैक्टिस हैऔर गतिशील कलाकारों को हर बार आपको संबंधों को व्यक्त करने में कठिनाइयाँ आती हैं। स्काला रनटाइम रूपांतरणों के बिना सांख्यिकीय रूप से वर्णन करने के लिए अधिक अभिव्यंजक शक्ति प्रदान करता है। और स्काला कोडिंग शैली कोड प्रकारों को रखने के लिए भारी प्रकार के निर्माणों का उपयोग करने के लिए प्रोत्साहित करती है।

ClassTagरेत TypeTags ऐसे इंस्ट्रूमेंट हैं जिनका उपयोग केवल के साथ किया जा सकता हैसांख्यिकीय रूप से टाइप किया गया कोड। उनके पास वर्ग और प्रकार की जानकारी है जो संकलन समय के दौरान संकलक ने प्राप्त की है। अगर यह प्रकारों को वैधानिक रूप से प्राप्त कर सकता है तो यह आपके लिए इस प्रकार तक पहुँचने के लिए टाइप टैग प्रदान कर सकता है।

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


जवाब के लिए 0 № 2

इन मामलों में आप का उपयोग करने पर विचार कर सकते हैं Typeable प्रकार वर्ग आप के साथ मिल निराकार प्रकार सुरक्षित casts के लिए । जैसे.:

scala> import shapeless.syntax.typeable._
import shapeless.syntax.typeable._

scala> val b: Any = List(1, 2, 3)
b: Any = List(1, 2, 3)

scala> b.cast[List[String]]
res1: Option[List[String]] = None

scala> b.cast[List[Int]]
res2: Option[List[Int]] = Some(List(1, 2, 3))

जैसा कि आप कर सकते है cast[T] विधि, के माध्यम से निराकार द्वारा हर प्रकार के लिए जोड़ा implicits, रिटर्न एक Option[T] जिसका मूल्य है None यदि कास्ट विफल रहता है, Some यदि यह "सफल एस ।

यदि आपको ऐसा लगता है कि आप स्रोत कोड देख सकते हैं typeable। हालाँकि, मेरा सुझाव है कि ऐसा करने से पहले आपको एक अच्छा कप कॉफी मिल जाए। :)