2011-05-18 10 views
146

मैं this question से कोड के इस तरह के एक टुकड़ा:स्कैला में `: _ *` (कोलन अंडरस्कोर स्टार) क्या करता है?

def addChild(n: Node, newChild: Node) = n match { 
    case Elem(prefix, label, attribs, scope, child @ _*) => Elem(prefix, label, attribs, scope, child ++ newChild : _*) 
    case _ => error("Can only add children to elements!") 
} 

उस में सब कुछ बहुत स्पष्ट है, इस टुकड़े को छोड़कर: child ++ newChild : _* यह क्या करता है? मैं स्टैंड के तहत सीक [नोड] एक और नोड के साथ मिलकर है, और फिर? : _* क्या करता है?

+42

शीर्षक में (कोलन अंडरस्कोर स्टार) जोड़ने के लिए बहुत बहुत धन्यवाद! – Gal

उत्तर

110

यह "splats" अनुक्रम। निर्माता हस्ताक्षर

new Elem(prefix: String, label: String, attributes: MetaData, scope: NamespaceBinding, 
     child: Node*) 

जो

new Elem(prefix, label, attributes, scope, 
     child1, child2, ... childN) 

के रूप में कहा जाता है, लेकिन यहाँ वहाँ केवल एक दृश्य, नहीं child1, child2, आदि है पर

देखो तो यह परिणाम अनुक्रम होने की अनुमति देता कन्स्ट्रक्टर के इनपुट के रूप में इस्तेमाल किया।

हैप्पी कोडिंग।


यह यहां एसएलएस में एक cutesy-नाम नहीं है, लेकिन विवरण हैं। प्राप्त करने की महत्वपूर्ण बात यह है कि यह बदलता है कि स्कैला दोहराए गए पैरामीटर के साथ विधि के तर्कों को कैसे बांधता है (जैसा ऊपर Node* के साथ दर्शाया गया है)।

_* टाइप एनोटेशन एसएलएस के "4.6.2 दोहराए गए पैरामीटर" में शामिल है।

एक पैरामीटर अनुभाग का अंतिम मान पैरामीटर "*", उदा निर्धारित फाई प्रत्यय किया जा सकता है (..., एक्स: टी *)। विधि के अंदर इस तरह के दोहराए गए पैरामीटर का प्रकार अनुक्रम प्रकार scala.Seq [टी] है। दोहराए गए पैरामीटर के साथ तरीके टी * टाइप टी के तर्कों की एक चर संख्या ले लो। यही है, यदि (पी 1: टी 1, ...।, पीएन: टीएन, पीएस: एस *) यू के साथ एक विधि एम तर्कों (ई 1, ..., ईके) पर लागू होता है जहां k> = n, फिर एम को उस एप्लिकेशन में टाइप करने के लिए लिया जाता है (पी 1: टी 1, ...।, पीएन: टीएन, पीएस: एस, ..., ps0S) यू, एस एस की घटनाओं के साथ एस एस जहां पीएस से परे कोई पैरामीटर नाम हैं ताजा। इस नियम का एकमात्र अपवाद यह है कि अंतिम तर्क को _ * प्रकार एनोटेशन के माध्यम से अनुक्रम तर्क के रूप में चिह्नित किया गया है। यदि उपर्युक्त एम तर्कों (ई 1, ..., एन, ई0: _ *) पर लागू होता है, तो उस एप्लिकेशन में एम का प्रकार (पी 1: टी 1, ...।, पीएन: टीएन, पीएस: स्केला।Seq [एस])

+3

हम इसे "स्मूच ऑपरेटर" कहते हैं, भले ही यह वास्तव में एक ऑपरेटर नहीं है :) –

+0

पायथन में इसे – joshlk

+0

अनपॅकिंग कहा जाता है क्या अनुक्रम कितना समय हो सकता है, जैसे कि जावा varargs के साथ है? – qwwqwwq

72
  • child ++ newChild - अनुक्रम
  • : - प्रकार जोड़ना, एक संकेत मदद करता है कि संकलक को समझने के लिए, क्या करता है प्रकार है कि अभिव्यक्ति
  • _* है - प्लेसहोल्डर किसी भी मूल्य को स्वीकार + vararg ऑपरेटर

child ++ newChild : _*Seq[Node] फैलाता है Node* (संकलक को बताता है कि हम अनुक्रम की तुलना में एक varargs के साथ काम कर रहे हैं)। उन विधियों के लिए विशेष रूप से उपयोगी जो केवल varargs स्वीकार कर सकते हैं।

+0

क्या आप "टाइप टाइप" के बारे में अधिक लिख सकते हैं? यह क्या है और यह कैसे काम करता है? – amorfis

+8

http://stackoverflow.com/questions/2087250/what-is-the-purpose-of-type-ascription-in-scala –

1

सभी उपरोक्त उत्तर बहुत अच्छे लगते हैं, लेकिन इसे समझाने के लिए बस एक नमूना की आवश्यकता है। संदेश यह है:

val x : Seq[Seq[Int]] = Seq(Seq(1),Seq(2)) 

def f(arg: Seq[Any]*) : Int = { 
arg.length 
} 
f(x) //1 as x is taken as single arg 
f(x:_*) // 2 as x is "unpacked" as a Seq[Any]* 

तो अब हम जानते क्या कर :_* संकलक बताने के लिए है: इस तर्क को खोल कृपया और समारोह कॉल में vararg पैरामीटर के लिए उन तत्वों के लिए बाध्य करने के बजाय एक भी तर्क के रूप में एक्स ले लो।

तो संक्षेप में, :_* vararg पैरामीटर को तर्क पारित करते समय अस्पष्टता को दूर करना है।

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