Vai a decomprimere array come argomenti


103

Quindi in Python e Ruby c'è l'operatore splat (*) per decomprimere un array come argomenti. In Javascript c'è la funzione .apply (). C'è un modo per decomprimere un array / slice come argomenti di funzione in Go? Anche qualsiasi risorsa per questo sarebbe ottima!

Qualcosa sulla falsariga di questo:

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

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

Mi scuso se sto commettendo errori sintattici / assortiti. Sono nuovo di Go.


4
Prima di tutto, arrnon è un array. È una fetta .
newacct

Risposte:


159

Puoi usare una sintassi vararg simile a 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)
}

Ora puoi sommare tutte le cose che desideri. Notare l'importante ...dopo quando si chiama la my_funcfunzione.

Esempio in esecuzione: http://ideone.com/8htWfx


8

O la tua funzione è varargs, in cui puoi usare una fetta con la ...notazione come mostra Hunter McMillen, oppure la tua funzione ha un numero fisso di argomenti e puoi decomprimerli quando scrivi il tuo codice.

Se vuoi davvero farlo dinamicamente su una funzione di un numero fisso di argomenti, puoi usare la riflessione:

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

Sono curioso di vedere come questo benchmark rispetto all'approccio varargs. Presumo che funzionerebbe in modo meno efficiente, ma dovrò esaminarlo.
Hunter McMillen

@HunterMcMillen hai avuto un'idea del confronto delle prestazioni?
AkiRoss

@AkiRoss probabilmente, ma è passato tanto tempo che ho dimenticato i risultati: |
Hunter McMillen

lol ok, non è un grosso problema: suppongo che sia più lento comunque, forse farò alcuni test da solo. Grazie
AkiRoss

0

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

Avevo un motivo per decomprimere alcune variabili da una stringa map [stringa] con virgolette singole attorno ad alcune di esse e senza. Ecco la logica per questo e il collegamento di riproduzione in alto ha lo snippet funzionante.

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}

Che si presenta in modo pulito per una query mssql come:

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

No, non c'è supporto diretto per questo nella lingua. Python e Ruby, così come Javascript che stai menzionando; sono tutti linguaggi dinamici / di scripting. Go è molto più vicino, ad esempio, al C che a qualsiasi linguaggio dinamico. La funzionalità "applica" è utile per i linguaggi dinamici, ma di scarsa utilità per linguaggi statici come C o Go,


@ user7610 ti sbagli. Ti riferisci a un caso diverso da quello in questione. Nella domanda originale non esiste un parametro variadico nella dichiarazione di funzione.
user2846569

Sì, lo ero, immagino. Quello che fa Python / Ruby può essere pensato come zucchero sintattico per la chiamata riflessiva che Go supporta ...
user7610
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.