Ir a desempaquetar la matriz como argumentos

103

Entonces, en Python y Ruby existe el operador splat (*) para descomprimir una matriz como argumentos. En Javascript existe la función .apply (). ¿Hay alguna forma de descomprimir una matriz / porción como argumentos de función en Go? ¡Cualquier recurso para esto también sería genial!

Algo parecido a esto:

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

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

Me disculpo si estoy cometiendo errores sintácticos / variados. Soy nuevo en Go.

Eatonphil
fuente
4
En primer lugar, arrno es una matriz. Es una rebanada .
newacct

Respuestas:

159

Puede usar una sintaxis de vararg similar 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)
}

Ahora puedes sumar tantas cosas como quieras. Observe el importante ...después cuando llame a la my_funcfunción.

Ejemplo de ejecución: http://ideone.com/8htWfx

Hunter McMillen
fuente
8

O tu función es varargs, en la que puedes usar un segmento con la ...notación como muestra Hunter McMillen, o tu función tiene un número fijo de argumentos y puedes descomprimirlos al escribir tu código.

Si realmente desea hacer esto dinámicamente en una función de un número fijo de argumentos, puede usar la reflexión:

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
fuente
Tengo curiosidad por ver cómo se acercan estos puntos de referencia contra los varargs. Asumiría que funcionaría de manera menos eficiente, pero tendré que investigarlo.
Hunter McMillen
@HunterMcMillen, ¿obtuvo alguna idea sobre la comparación de rendimiento?
AkiRoss
@AkiRoss probablemente, pero fue hace tanto tiempo que he olvidado los resultados: |
Hunter McMillen
lol ok, no es gran cosa: supongo que es más lento de todos modos, tal vez yo mismo haga algunas pruebas. Gracias
AkiRoss
0

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

Tenía una razón para descomprimir algunas variables de una cadena de mapa [cadena] con comillas simples alrededor de algunas de ellas, así como sin ellas. Aquí está la lógica y el enlace de reproducción en la parte superior tiene el fragmento de trabajo completo.

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}

Que se presenta limpiamente para una consulta mssql como:

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
fuente
-16

No, no hay soporte directo para esto en el idioma. Python y Ruby, así como Javascript que estás mencionando; son todos lenguajes dinámicos / de secuencias de comandos. Go está mucho más cerca, por ejemplo, de C que de cualquier lenguaje dinámico. La funcionalidad 'aplicar' es útil para lenguajes dinámicos, pero de poca utilidad para lenguajes estáticos como C o Go,

zzzz
fuente
@ user7610 estás equivocado. Se está refiriendo a un caso diferente al de la pregunta. En la pregunta original, no hay un parámetro variable en la declaración de función.
user2846569
Sí, lo estaba, supongo. Lo Python / Ruby no puede ser pensado como el azúcar sintáctica para la llamada de reflexión que los apoyos Go ...
user7610