Escribir en la llamada de función golang recursiva

Estoy trabajando para agregar 'comodines de matriz' a un proyecto Go en Github llamado jsonget. Aquí hay un ejemplo de lo que quiero decir con comodines de matriz:

 > echo "[{product:'coffee', price:2.10}, {product:'beer', price:3.80}]" | jsonget '*.price'

[2.10, 3.80]

El código de mi sucursal es aquí

El problema al que me estoy enfrentando es al escribir, cuando GetValue encuentra un * carácter, se repite, llamando GetValue en la subexpresión, pero el tipo siempre regresa como una cadena.

Por ejemplo, en el archivo de prueba, le doy esta pieza de json:

    {
      "inventory": [
          {"name": "mountain bike", "price": 251.0},
          {"name": "red wagon", "price": 90.10},
          {"name": "kinesis advantage", "price": 300.0},
          {"name": "a ticket to Mars", "price": 1200000000.0}
      ]
    }

Entonces consulta inventory[*].price, esperando [251,90.1,300,1.2e+09], pero en lugar de obtener ["251","90.1","300","1.2e+09"].

Me gustaría evitar usar la reflexión aquí, pero no veo otra forma de hacerlo.

preguntado el 15 de mayo de 13 a las 04:05

Sería útil publicar un fragmento de código que destaque el problema. -

Su biblioteca se define dentro del main paquete: debe corregir la estructura de su proyecto. -

1 Respuestas

Pido disculpas si he entendido mal su pregunta, pero espero que esto ayude.

Creo que vas a tener que usar la reflexión o un cambio de tipo (http://golang.org/doc/effective_go.html#type_switch , que probablemente usa reflejo detrás de escena, no estoy seguro de eso).

No debería ser demasiado difícil modificar su existente valueToString función para incluir un interruptor de tipo. Posiblemente cambiarle el nombre a convertValue o algo más genérico, y ponle un interruptor de tipo. Si el valor es un int, devuelve un int, de lo contrario, devuelve una cadena.

Por ejemplo:

func convertValue(value interface{}) (text string, i int, err error) { // Was valueToString
    if value == nil && *printNulls == false {
        return "", nil, nil
    }

    textBytes, err := json.Marshal(value)
    if err != nil {
        return "", nil, err
    }
    switch value := value.(type) {
    default:
        text = string(textBytes)
        text = quotedString.ReplaceAllString(text, "$1")
        return text, nil, nil
    case int:
        i = textBytes
        return nil, i, nil
    }
}

Esa voluntad Ojalá string() todo excepto los valores que el interruptor de tipo detecta como enteros, que se devolverán tal como son.

Probablemente haya una forma más limpia de hacerlo, pero es casi seguro que implicaría una gran refactorización de código. El principal inconveniente es que ahora debe verificar si un valor es nulo antes de usarlo.

No estoy seguro de si hay una manera de hacer que una sola función pueda devolver un valor de varios tipos, ya que estoy bastante seguro de que causaría estragos en la seguridad de tipos. Si es posible, solo me puedo imaginar haciéndolo volver una interfaz vacía en la definición de la función. Suena desordenado.

EDITAR: Echa un vistazo a la publicación de blog de Andrew Gerrand http://blog.golang.org/2011/01/json-and-go.html , especialmente el bit cerca de la parte inferior sobre la decodificación de datos genéricos. Debería ayudar.

contestado el 15 de mayo de 13 a las 16:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.