2016-06-05 4 views
5

मैप्स पर समझ के लिए दृश्यों के पीछे चल रहे टाइपिंग से उलझन में हूं। मैं समझता हूँ कि बाहरी संग्रह प्रकार आम तौर पर संरक्षित किया जाना माना जाता है है, और हम देखते हैं कि निम्नलिखित दो मामलों में अपेक्षित व्यवहार:स्कैला - समझ के लिए मानचित्र से Iterable तक अप्रत्याशित प्रकार स्विच?

scala> for { 
    | (k,v) <- Map(0->1,2->3) 
    | } yield k -> v 
res0: scala.collection.immutable.Map[Int,Int] = Map(0 -> 1, 2 -> 3) 

scala> for { 
    | (k,v) <- Map(0->1,2->3) 
    | foo = 1 
    | } yield k -> v 
res1: scala.collection.immutable.Map[Int,Int] = Map(0 -> 1, 2 -> 3) 

लेकिन जब मैं समझ के लिए अंदर एक दूसरे काम जोड़ने मैं कुछ आश्चर्य की बात मिलती है:

scala> for { 
    | (k,v) <- Map(0->1,2->3) 
    | foo = 1 
    | bar = 2 
    | } yield k -> v 
res2: scala.collection.immutable.Iterable[(Int, Int)] = List((0,1), (2,3)) 

ऐसा क्यों हो रहा है?

उत्तर

5

यदि आप scala -Xprint:typer -e "for { ... } yield k->v" चलाते हैं, तो आप कोड का एक डी-शक्कर संस्करण प्राप्त कर सकते हैं।

val m: Map[Int,Int] = Map(0->1, 2->3) 
m.map { 
    case x @ (k,v) => 
    val foo = 1 
    val bar = 2 
    (x, foo, bar) 
}.map { 
    case ((k,v), foo, bar) => (k, v) 
} 

तो आप क्या देखेंगे कि जब के लिए-समझ एक .map कॉल में परिवर्तित हो जाता है, यह वास्तव foo और bark->v के साथ लौट रहा है: यहाँ आप क्या मिलेगा की एक बहुत सरलीकृत संस्करण है , जिसका मतलब है कि यह Tuple3[(Int,Int), Int, Int] है। चूंकि Tuple3 वस्तुओं के पुनरावृत्त को Map में परिवर्तित नहीं किया जा सकता है, ऐसा लगता है कि इसे Iterable वापस करना होगा। हालांकि, ताकि सही उत्पादन, जो Tuple2 वस्तुओं का संग्रह है प्राप्त करने के लिए, यह एक माध्यमिक .map कि Tuple3 से foo और bar को छोड़ देता है करता है, लेकिन इस समय यह नहीं रह गया है जानता है कि यह एक Map किया जाना चाहिए था, क्योंकि जब आप चेन .map पर कॉल करता है कि जानकारी आगे नहीं ले जाती है।

केवल एक असाइनमेंट के साथ आपका उदाहरण भाग्यशाली हो जाता है क्योंकि मध्यवर्ती प्रतिनिधित्व Tuple2[(Int,Int), Int] है।

दूसरी ओर, यदि आप एक .map सीधे उपयोग करते हैं, यह काम करता है:

Map(0->1, 2->3).map { 
    case (k,v) => 
    val foo = 1 
    val bar = 2 
    k -> v 
} 
संबंधित मुद्दे