क्या होता है परम: _ * स्काला में मतलब है?


87

स्काला (2.9.1) के लिए नया होने के नाते, मेरे पास है List[Event]और मैं इसे कॉपी करना चाहूंगा Queue[Event], लेकिन Queue[List[Event]]इसके बजाय निम्नलिखित सिंटैक्स का परिणाम होगा:

val eventQueue = Queue(events)

किसी कारण के लिए, निम्नलिखित काम करता है:

val eventQueue = Queue(events : _*)

लेकिन मैं यह समझना चाहता हूं कि यह क्या करता है, और यह क्यों काम करता है? मैंने पहले ही Queue.applyसमारोह के हस्ताक्षर को देखा :

def apply[A](elems: A*)

और मैं समझता हूं कि पहला प्रयास काम क्यों नहीं करता है, लेकिन दूसरे का अर्थ क्या है? इस मामले में क्या है :, और फ़ंक्शन केवल एक _*को क्यों नहीं applyलेता है Iterable[A]?

जवाबों:


93

a: Aटाइप अस्क्रिप्शन है; देखिए कि स्काला में टाइप एशेज का उद्देश्य क्या है?

: _* टाइप एस्क्रिप्शन का एक विशेष उदाहरण है जो संकलक को अनुक्रम प्रकार के एकल तर्क को वैरिएबल लॉजिक अनुक्रम के रूप में मानता है, अर्थात वैरगैस।

यह Queueउपयोग करने के लिए पूरी तरह से वैध Queue.applyहै जिसमें एक एकल तत्व है जो एक अनुक्रम या पुनरावृत्ति है, इसलिए जब आप एकल देते हैं तो यही होता है Iterable[A]


83

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

यह एक प्रकार का एनोटेशन है जो एक अनुक्रम तर्क को इंगित करता है और भाषा के खंड के सामान्य 4.6.2, "दोहराए गए पैरामीटर" में सामान्य नियम के "अपवाद" के रूप में उल्लेख किया गया है।

यह तब उपयोगी होता है जब कोई फ़ंक्शन विभिन्न प्रकार के तर्कों को लेता है, उदाहरण के लिए एक फ़ंक्शन जैसे कि def sum(args: Int*), जिसे इस प्रकार लागू किया जा सकता है sum(1), sum(1,2)आदि। यदि आपके पास एक सूची है जैसे xs = List(1,2,3), तो आप xsस्वयं को पास नहीं कर सकते , क्योंकि यह एक के Listबजाय है Int, लेकिन आप इसके तत्वों का उपयोग कर सकते हैं sum(xs: _*)


def sum(xs: _*)'एरर: अनबाउंड वाइल्डकार्ड टाइप' फेंकता है
7kemZmani

आपका उत्तर स्पष्ट है, लेकिन यह वास्तव में मेरे लिए और अधिक भ्रम पैदा कर रहा है, आमतौर पर स्लाला का xs: intमतलब है कि एक्स का प्रकार इंट है, इसके द्वारा स्कैला में उपर्युक्त सिंटैक्स होता है, जहां xs: _*एक्सएस अपने व्यक्तिगत सदस्यों को डाला जाता है।
Rpant

उपरोक्त लिंक का अनुसरण किया और जैसा दिखता है वैसा ही होता है, टाइप टाइपिंग जावा टाइप कास्टिंग के लिए एक स्कैला शब्दावली है। कृपया गलत होने पर मुझे सुधारें।
Rpant

2
@ 7kemZmani: आपको फ़ंक्शन को एक विशिष्ट var-args प्रकार के साथ परिभाषित करना होगा: def sum(args: Int*)और आप इसे वाइल्डकार्ड "जेनेरिक" var-args प्रकार के साथ कहते हैं val a = sum(xs: _*):। _*"मैं एक इंट *, या एक स्ट्रिंग *, या कुछ भी * के बारे में सोचता हूं जो कि विधि हस्ताक्षर में परिभाषित है"
अल्फोंसो निशिकवा

10

अजगर लोगों के लिए:

स्काला का _*ऑपरेटर कमोबेश पायथन के * -ऑपरेटर के बराबर है ।


उदाहरण

लुइगी प्लिंज द्वारा उपलब्ध कराए गए लिंक से स्केला का उदाहरण प्रस्तुत करना :

def echo(args: String*) = 
    for (arg <- args) println(arg)

val arr = Array("What's", "up", "doc?")
echo(arr: _*)

अजगर की तरह दिखेगा:

def echo(*args):
    for arg in args:
        print "%s" % arg

arr = ["What's", "up", "doc?"]
echo(*arr)

और दोनों निम्नलिखित आउटपुट देते हैं:

क्या है
अप
डॉक?


अंतर: स्थितीय मापदंडों को खोलना

जबकि पायथन के *-ऑपरेटर फिक्स्ड-एरिटी फ़ंक्शंस के लिए स्थितीय मापदंडों / मापदंडों के अनपैकिंग से भी निपट सकते हैं:

def multiply (x, y):
    return x * y

operands = (2, 4)
multiply(*operands)

8

स्केल के साथ भी ऐसा ही करना:

def multiply(x:Int, y:Int) = {
    x * y;
}

val operands = (2, 4)
multiply (operands : _*)

असफल हो जायेगी:

विधि के लिए पर्याप्त तर्क नहीं हैं: (x: Int, y: Int) Int।
अनिर्दिष्ट मूल्य पैरामीटर y।

लेकिन स्कैला के साथ इसे प्राप्त करना संभव है:

def multiply(x:Int, y:Int) = {
    x*y;
}

val operands = (2, 4)
multiply _ tupled operands

लोरिन नेल्सन के अनुसार यह कैसे काम करता है:

पहला भाग, f _, आंशिक रूप से लागू फ़ंक्शन के लिए वाक्यविन्यास है जिसमें कोई भी तर्क निर्दिष्ट नहीं किया गया है। यह फंक्शन ऑब्जेक्ट की पकड़ पाने के लिए एक तंत्र के रूप में काम करता है। tupled एक नया फंक्शन देता है जो arity-1 का है जो एक सिंगल एरिटी-n tuple लेता है।

भविष्य वाचन:

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.