2013-06-24 9 views
5

मैं HashMaps के लिए toArray की परिभाषा देख रहा था:स्केलैडोक का कहना है कि हैश मैप.तोएरे ऐरे [ए] बी के बजाय ऐरे [ए] लौटाता है [? ए, बी)]?

http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.HashMap

यह है

toArray: Array[A] 
def toArray[B >: (A, B)](implicit arg0: ClassTag[B]): Array[B] 

मैं काफी यह समझ में नहीं आता - पहली बिट कहते हैं कि आप किसी सरणी मिल [एक] , लेकिन दूसरा भाग कहता है कि आपको ऐरे [बी] मिलता है? इनमें से कोई भी मैं क्या उम्मीद कर रहे हैं - सरणी [(ए, बी)]

जब मैं इसे अपने आप की जाँच करें:

scala> val x = scala.collection.mutable.HashMap[String, Int]() 
x: scala.collection.mutable.HashMap[String,Int] = Map() 

scala> x.put("8", 7) 
res0: Option[Int] = None 

scala> x foreach println 
(8,7) 

scala> x.toArray 
res2: Array[(String, Int)] = Array((8,7)) 

कारण है कि यह toList की तरह नहीं है?

toList: scala.List[(A, B)] 
+0

के दो उदाहरणों को समर्पित करने में असफल रहा, सभी उत्कृष्ट उत्तर, धन्यवाद! – Austin

उत्तर

5

स्केलैडोक में सभी प्रकार की सूक्ष्म बग हैं। यहां समस्या यह है कि आप विधि हस्ताक्षर के "सरलीकृत" संस्करण को देख रहे हैं (हस्ताक्षर के आवश्यक भाग को व्यक्त करने के तरीके के रूप में और CanBuildFrom जैसे map/flatMap विधियों को छुपाएं, जो वास्तव में कार्यान्वयन विवरण हैं)। सरलीकरण यहां थोड़ी भयानक हो गया, और यह बहुत समझ में नहीं आता है। ,

def toArray[B >: (A, B)](implicit arg0: ClassTag[B]): Array[B] 

वास्तव में यह अभी भी गलत है के रूप में हम निश्चित रूप से एक ग्रुप बी नहीं हो सकता जहां B>: आप 'पूर्ण हस्ताक्षर "पर क्लिक करते हैं लिंक, आपको लगता है कि वास्तविक हस्ताक्षर दिखाई देगा की तरह (ए, बी)। यह होना चाहिए और अधिक की तरह:

def toArray[C >: (A, B)](implicit arg0: ClassTag[C]): Array[C] 

समस्या वहाँ वास्तव में हैं कि दो B रों है: पहले एक HashMap वर्ग घोषणा ही (HashMap[A, +B]) से है, जबकि अन्य एक तरीकों toArray इसके आधार में परिभाषित से आता है आता है कक्षा TraversableOnce (def toArray[B >: A](implicit arg0: ClassTag[B]): Array[B])। ऐसा होता है कि स्केलैड जनरेटर B

2

एपीआई आप toArray की Scaladoc में देखें:

def toArray[B >: (A, B)](implicit arg0: ClassTag[B]): Array[B] 

के बराबर है:

def toArray[C >: (A, B)](implicit arg0: ClassTag[C]): Array[C] 

प्रकार की पसंद चर B वास्तव में दुर्भाग्यपूर्ण है (और शायद एक स्कालाडॉक बग, मुझे यकीन नहीं है कि आपको इसे लिखने की अनुमति है या नहीं)।

यह मूल रूप से आप (A,B)के सबसे विशिष्ट महाप्रकार जिसके लिए एक ClassTag उपलब्ध है की एक सरणी मिल जाएगा मतलब है। Array बनाने के लिए ClassTag आवश्यक है।

इसका मूल रूप से अर्थ है कि यदि संकलन समय पर Map का रन टाइम प्रकार आप कनवर्ट कर रहे हैं, तो आपको Array[(A,B)] मिल जाएगा। हालांकि, अगर आपने कहीं Map को अप-कास्ट किया है, तो परिणामी Array का रन-टाइम प्रकार अप-कास्ट प्रकार पर निर्भर करेगा, न कि रनटाइम प्रकार पर। यह toList से भिन्न व्यवहार है और देशी arrays कैसे बनाया जा सकता है पर JVMs प्रतिबंधों के कारण। क्योंकि यह TraversableOnce से toArray, विरासत में जहां संग्रह के प्रकार A है और वापसी मान B है

1

Scaladoc सिर्फ गलत है। Array[A] चीज TraversableOnce से अधिक है जहां A है जो भी TraversableOnce ट्रैवर्सिंग है (इस मामले में, वास्तव में (A,B)A और B की एक अलग परिभाषा के लिए); और हालांकि यह (A,B) को लंबे रूप में ठीक से भरता है, फिर भी यह को C जैसे किसी भिन्न अक्षर के बजाय नए रिटर्न वैरिएबल के रूप में उपयोग करता है।

भ्रमित करने की तरह! यह वास्तव में

def toArray[C >: (A,B)](...[C]): Array[C] 

पढ़ना चाहिए और संक्षिप्त रूप

toArray: Array[(A,B)] 

होना चाहिए, जैसा कि आपने उम्मीद है।

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