Déballer le tableau en tant qu’arguments


104

Donc, en Python et Ruby, il y a l'opérateur splat (*) pour décompresser un tableau en arguments. En Javascript, il y a la fonction .apply (). Existe-t-il un moyen de décompresser un tableau / une tranche en tant qu'arguments de fonction dans Go? Toutes les ressources pour cela seraient également formidables!

Quelque chose dans le sens de ceci:

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

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

Je m'excuse si je fais des erreurs syntaxiques / assorties. Je suis nouveau sur Go.


4
Tout d'abord, arrn'est pas un tableau. C'est une tranche .
newacct

Réponses:


160

Vous pouvez utiliser une syntaxe vararg similaire à C:

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)
}

Vous pouvez maintenant additionner autant de choses que vous le souhaitez. Notez l'important ...après lorsque vous appelez la my_funcfonction.

Exemple d'exécution: http://ideone.com/8htWfx


8

Soit votre fonction est varargs, dans laquelle vous pouvez utiliser une tranche avec la ...notation comme le montre Hunter McMillen, soit votre fonction a un nombre fixe d'arguments et vous pouvez les décompresser lors de l'écriture de votre code.

Si vous voulez vraiment faire cela dynamiquement sur une fonction de nombre fixe d'arguments, vous pouvez utiliser la réflexion:

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)
}

Je suis curieux de voir comment cela se compare à l'approche varargs. Je suppose que cela fonctionnerait moins efficacement, mais je vais devoir l'examiner.
Hunter McMillen

@HunterMcMillen avez-vous eu un aperçu de la comparaison des performances?
AkiRoss le

@AkiRoss probablement, mais il y a si longtemps que j'ai oublié les résultats: |
Hunter McMillen

lol ok, pas grave: je suppose que c'est plus lent de toute façon, peut-être que je vais faire des tests moi-même. Thanx
AkiRoss

0

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

J'ai eu une raison de décompresser certains vars d'une chaîne map [string] avec des guillemets simples autour de certains d'entre eux ainsi que sans. Voici la logique pour cela et le lien de lecture en haut contient l'extrait de code complet.

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}

Qui se présente proprement pour une requête mssql comme:

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');

-16

Non, il n'y a pas de support direct pour cela dans la langue. Python et Ruby, ainsi que Javascript que vous mentionnez; sont tous des langages dynamiques / de script. Go est bien plus proche, par exemple, de C que de n'importe quel langage dynamique. La fonctionnalité `` appliquer '' est pratique pour les langages dynamiques, mais peu utile pour les langages statiques comme C ou Go,


@ user7610 vous vous trompez. Vous faites référence à un cas différent de celui en question. Dans la question d'origine, il n'y a pas de paramètre variadique dans la déclaration de fonction.
user2846569

Ouais, je l'étais, je suppose. Ce que fait Python / Ruby peut être considéré comme du sucre syntaxique pour l'appel réflexif pris en charge par Go ...
user7610
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.