Eine Liste oder Karte als Funktionsargumente in Scala einpacken

Ist es möglich, eine Liste / Tupel / Kartenelemente als Argumente für eine Funktion in Scala dynamisch zu entpacken? Ich suche ein Scala-Äquivalent von Pythons kwargs / kwargs .

Wenn z. B. in Python eine Funktion als def foo(bar1, bar2, bar3=None, bar4=1) definiert ist def foo(bar1, bar2, bar3=None, bar4=1) dann erhält man eine Liste x=[1,7] und ein Wörterbuch y={'bar3':True, 'bar4':9} Du kannst foo als foo(*x, **y) anrufen.

3 Solutions collect form web for “Eine Liste oder Karte als Funktionsargumente in Scala einpacken”

Nur um klar zu sein, gilt der folgende Python-Code:

 def foo(bar1, bar2, bar3=None, bar4=1): print("bar1="+str(bar1)+" bar2="+str(bar2)+" bar3="+str(bar3)+" bar4="+str(bar4)) x=[1,7] y={'bar3':True, 'bar4':9} foo(*x,**y) 

Allerdings gibt es keine analoge Scala-Syntax. Es gibt einige ähnliche Dinge, aber der Hauptgrund, dass dies niemals möglich sein wird, ist, dass es die Compile-Time-Typ-Überprüfung, die Scala erfordert verletzen würde. Schauen wir uns genauer an.

Die Gründe

Zuerst denke an den varargs portion Hier willst du in der Lage sein, eine beliebige Liste von Argumenten zu übergeben und die entsprechenden Funktionsparameter auszufüllen. Dies wird niemals in Scala funktionieren, da der Typcheck erfordert, dass die Parameter, die in eine Funktion übergeben werden, gültig sind. In deinem Szenario kann foo() eine Parameterliste x der Länge zwei akzeptieren, aber nicht weniger. Aber da jeder Seq eine beliebige Anzahl von Parametern haben kann, wie würde der Typchegler wissen, dass der x , der übergeben wird, zum Zeitpunkt der Kompilierung gültig ist?

Zweitens denke an die Keywword-Argumente. Hier forderst du die Funktion, eine beliebige Map von Argumenten und Werten zu akzeptieren. Aber Sie bekommen das gleiche Problem: Wie kann der Compile-Time-Checker wissen, dass Sie alle notwendigen Argumente übergeben? Oder weiter, dass sie die richtigen Typen sind? Immerhin, sie Beispiel gibt es eine Karte mit einem Booleschen und einem Int, die den Typ Map[String, Any] , also wie würde der Typchegler wissen, dass dies mit Ihren Parametertypen übereinstimmen würde?

Einige Lösungen

Scala's varargs

Sie können einige ähnliche Dinge machen, aber nicht genau das. Wenn Sie z. B. Ihre Funktion definieren, um varargs explizit zu verwenden, können Sie eine Seq:

 def foo(bar1: Int*) = println(f"bar1=$bar1") val x = Seq(1, 2) foo(x:_*) 

Das funktioniert, weil Scala weiß, dass es nur eine Sequenz von null oder mehr Argumenten braucht, und ein Seq wird immer null oder mehr Items enthalten, also passt es zusammen. Außerdem funktioniert es nur, wenn die Typen auch übereinstimmen; Hier erwartet man eine Folge von Ints und bekommt es.

tupled

Das andere, was du tun kannst, ist, ein Tupel von Argumenten zu übergeben:

 def foo(bar1: Int, bar2: Int, bar3: Boolean = false, bar4: Int = 1) = println(f"bar1=$bar1 bar2=$bar2 bar3=$bar3 bar4=$bar4") val x = (1, 2, true, 9) (foo _).tupled(x) 

Auch dies funktioniert, weil Scala's Typ Checker kann überprüfen, dass die Argumente gültig sind. Die Funktion erfordert vier Argumente der Typen Int, Int, Boolean und Int, und da ein Tupel in Scala eine feste Länge und bekannte (und möglicherweise verschiedene) Typen für jede Position hat, kann der Typ-Checker überprüfen, ob die Argumente übereinstimmen Erwartete Parameter.

Ursprüngliche Antworten nicht erwähnen Handling Karte als Liste der Paare – es kann leicht in Karte umgewandelt werden (auch -> Betreiber ist nur kurzschrift für Paar).

 def parse(options: (String, String)*) = println (options.toMap) 

Sie können varargs syntax verwenden:

 def printAll(strings: String*) { strings.map(println) } 

Nein, Sie können diese Funktion auch verwenden:

 printAll("foo") 

damit:

 printAll("foo", "bar") 

oder so:

 printAll("foo", "bar", "baz") 
  • Wenn du Python als Unterprozeß anrufst, kann ich es zwingen, im interaktiven Modus zu laufen?
  • Scala-Äquivalent von Python-Echo-Server / Client-Beispiel?
  • Welche Programmiersprachen kann ich auf Android Dalvik verwenden?
  • Listing alle Dateien in Spark Cluster auf Hadoop HDFS mit Scala oder Python gespeichert?
  • Filter auf der Grundlage einer anderen RDD in Spark
  • Scala: Merkmal für ein Funktionsobjekt mit variablen Längenargumenten?
  • Einfache, problemlose, null-boilerplate serialisierung in Scala / Java ähnlich wie Python's Pickle?
  • Was ist der bevorzugte Weg, um 'Ertrag' in Scala zu implementieren?
  • Was bedeutet dieser Fehler (SimpleHttpConnectionManager wird falsch verwendet)?
  • Wie benutzt man eine Scala-Klasse in Pyspark
  • Starten Sie HiveThriftServer programmgesteuert in Python
  • Python ist die beste Programmiersprache der Welt.