list - स्कैला सूची concatenation,::: बनाम++




scala (3)

क्या स्कैला में सम्मिलित सूचियों के लिए ::: और ++ बीच कोई अंतर है?

scala> List(1,2,3) ++ List(4,5)
res0: List[Int] = List(1, 2, 3, 4, 5)

scala> List(1,2,3) ::: List(4,5)
res1: List[Int] = List(1, 2, 3, 4, 5)

scala> res0 == res1
res2: Boolean = true

प्रलेखन से ऐसा लगता है कि ++ अधिक सामान्य है जबकि ::: List विशिष्ट है। क्या उत्तरार्द्ध प्रदान किया गया है क्योंकि यह अन्य कार्यात्मक भाषाओं में उपयोग किया जाता है?


एक अलग बिंदु यह है कि पहली वाक्य के रूप में पार्स किया गया है:

scala> List(1,2,3).++(List(4,5))
res0: List[Int] = List(1, 2, 3, 4, 5)

जबकि दूसरा उदाहरण इस प्रकार विश्लेषण किया गया है:

scala> List(4,5).:::(List(1,2,3))
res1: List[Int] = List(1, 2, 3, 4, 5)

तो यदि आप मैक्रोज़ का उपयोग कर रहे हैं, तो आपको ध्यान रखना चाहिए।

इसके अलावा, दो सूचियों के लिए ++ कॉल कर रहा है ::: लेकिन अधिक ओवरहेड के साथ क्योंकि यह एक निर्माता को सूची से सूची में रखने के लिए एक अंतर्निहित मूल्य मांग रहा है। लेकिन माइक्रोबेंमार्क ने उस अर्थ में कुछ भी उपयोगी साबित नहीं किया, मुझे लगता है कि संकलक ऐसी कॉल को अनुकूलित करता है।

गर्म करने के बाद माइक्रो-बेंचमार्क।

scala>def time(a: => Unit): Long = { val t = System.currentTimeMillis; a; System.currentTimeMillis - t}
scala>def average(a: () => Long) = (for(i<-1 to 100) yield a()).sum/100

scala>average (() => time { (List[Int]() /: (1 to 1000)) { case (l, e) => l ++ List(e) } })
res1: Long = 46
scala>average (() => time { (List[Int]() /: (1 to 1000)) { case (l, e) => l ::: List(e ) } })
res2: Long = 46

जैसा कि डैनियल सी सोबराई ने कहा था, आप किसी भी संग्रह की सामग्री को ++ का उपयोग करके सूची में जोड़ सकते हैं, जबकि ::: आप केवल सूचियों को जोड़ सकते हैं।


विरासत। सूची को मूल रूप से कार्यात्मक-भाषा-दिखने के रूप में परिभाषित किया गया था:

1 :: 2 :: Nil // a list
list1 ::: list2  // concatenation of two lists

list match {
  case head :: tail => "non-empty"
  case Nil          => "empty"
}

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


::: केवल सूचियों के साथ काम करता है, जबकि ++ किसी भी ट्रैवर्स के साथ उपयोग किया जा सकता है। वर्तमान कार्यान्वयन (2.9.0) में, ++ वापस आ जाता है ::: यदि तर्क भी एक List





concatenation