Entpacken Sie das Array als Argumente

102

In Python und Ruby gibt es also den Splat-Operator (*) zum Entpacken eines Arrays als Argumente. In Javascript gibt es die Funktion .apply (). Gibt es eine Möglichkeit, ein Array / Slice als Funktionsargumente in Go zu entpacken? Alle Ressourcen dafür wären auch großartig!

Etwas in dieser Richtung:

func my_func(a, b int) (int) {
    return a + b
}

func main() {
    arr := []int{2,4}
    sum := my_func(arr)
}

Ich entschuldige mich, wenn ich syntaktische / verschiedene Fehler mache. Ich bin neu zu gehen.

Eatonphil
quelle
4
Erstens arrist es kein Array. Es ist eine Scheibe .
Newacct

Antworten:

157

Sie können eine Vararg-Syntax ähnlich C verwenden:

package main
import "fmt"

func my_func( args ...int) int {
   sum := 0
   for _,v := range args {
      sum = sum + v
   }

   return sum;
}

func main() {
    arr := []int{2,4}
    sum := my_func(arr...)
    fmt.Println("Sum is ", sum)
}

Jetzt können Sie so viele Dinge zusammenfassen, wie Sie möchten. Beachten Sie das Wichtige ...danach, wenn Sie die my_funcFunktion aufrufen .

Laufendes Beispiel: http://ideone.com/8htWfx

Hunter McMillen
quelle
8

Entweder ist Ihre Funktion varargs, in dem Sie ein Slice mit der ...Notation verwenden können, wie Hunter McMillen zeigt, oder Ihre Funktion hat eine feste Anzahl von Argumenten und Sie können sie beim Schreiben Ihres Codes entpacken.

Wenn Sie dies wirklich dynamisch für eine Funktion mit einer festen Anzahl von Argumenten tun möchten, können Sie Reflection verwenden:

package main
import "fmt"
import "reflect"

func my_func(a, b int) (int) {
    return a + b
}

func main() {
    arr := []int{2,4}
    var args []reflect.Value
    for _, x := range arr {
        args = append(args, reflect.ValueOf(x))
    }
    fun := reflect.ValueOf(my_func)
    result := fun.Call(args)
    sum := result[0].Interface().(int)
    fmt.Println("Sum is ", sum)
}
newacct
quelle
Ich bin gespannt, wie sich dieser Benchmark gegen den Varargs-Ansatz richtet. Ich würde annehmen, dass es weniger effizient funktioniert, aber ich muss es untersuchen.
Hunter McMillen
@HunterMcMillen Hast du einen Einblick in den Leistungsvergleich bekommen?
AkiRoss
@AkiRoss wahrscheinlich, aber es ist so lange her, dass ich die Ergebnisse vergessen habe: |
Hunter McMillen
lol ok, keine große Sache: Ich nehme an, es ist sowieso langsamer, vielleicht führe ich selbst einige Tests durch. Thanx
AkiRoss
0

https://play.golang.org/p/2nN6kjHXIsd

Ich hatte einen Grund, einige Vars aus einer Map [String] -String mit einfachen Anführungszeichen um einige von ihnen sowie ohne zu entpacken. Hier ist die Logik dafür und der Play Link oben hat das voll funktionsfähige Snippet.

func unpack(a map[string]string) string {

var stmt, val string
var x, y []string
for k, v := range a {
    x = append(x, k)
    y = append(y, "'"+v+"'")
}

stmt = "INSERT INTO tdo.rca_trans_status (" + strings.Join(x, ", ")
val = ") VALUES (" + strings.Join(y, ",") + ");"

return stmt + val}

Welches präsentiert sich sauber für eine mssql-Abfrage als:

INSERT INTO tdo.rca_trans_status (rca_json_body, original_org, md5sum, updated, rca_key) VALUES ('blob','EG','2343453463','2009-11-10 23:00:00','prb-180');
Bill H.
quelle
-15

Nein, dafür gibt es in der Sprache keine direkte Unterstützung. Python und Ruby sowie Javascript, das Sie erwähnen; sind alle dynamischen / Skriptsprachen. Go ist beispielsweise C viel näher als jeder dynamischen Sprache. Die Funktion 'Anwenden' ist praktisch für dynamische Sprachen, für statische Sprachen wie C oder Go jedoch von geringem Nutzen.

zzzz
quelle
@ user7610 du liegst falsch. Sie beziehen sich auf einen anderen Fall als den fraglichen. In der ursprünglichen Frage gibt es keinen variadischen Parameter in der Funktionsdeklaration.
user2846569
Ja, das war ich, denke ich. Was Python / Ruby tut, kann als syntaktischer Zucker für den reflektierenden Aufruf angesehen werden, den Go unterstützt ...
user7610