programacion - JSON Marshaling con números largos en Golang, da el número de coma flotante
punto flotante ejemplos (2)
El estándar JSON no tiene longs o floats, solo tiene números. El paquete json
asumirá float64 cuando no haya definido nada más (es decir, solo se proporciona Unmarshal
con una interface{}
).
Lo que debes hacer es crear una estructura apropiada (como lo mencionó Volker):
package main
import (
"encoding/json"
"fmt"
"os"
)
type Person struct {
Id int64 `json:"id"`
Name string `json:"name"`
}
func main() {
//Create the Json string
var b = []byte(`{"id": 12423434, "Name": "Fernando"}`)
//Marshal the json to a proper struct
var f Person
json.Unmarshal(b, &f)
//print the person
fmt.Println(f)
//unmarshal the struct to json
result, _ := json.Marshal(f)
//print the json
os.Stdout.Write(result)
}
Resultado:
{12423434 Fernando}
{"id": 12423434, "nombre": "Fernando"}
Área de juegos: http://play.golang.org/p/2R76DYVgMK
Editar:
En caso de que tenga una estructura json dinámica y desee utilizar los beneficios de una estructura, puede resolverla usando json.RawMessage
. Una variable de tipo json.RawMessage
almacenará la cadena JSON sin json.RawMessage
para que luego, cuando sepa qué tipo de objeto contenga, pueda descomponerla en la estructura adecuada. Independientemente de la solución que utilice, en cualquier caso necesitará alguna instrucción if
o switch
donde determine qué tipo de estructura es.
También es útil cuando partes de los datos JSON solo se copiarán en el otro objeto JSON, como con el id
valor de una solicitud JSON RPC.
Ejemplo de contenedor struct usando json.RawMessage y los datos JSON correspondientes:
type Container struct {
Type string `json:"type"`
Data json.RawMessage `json:"data"`
}
var b = []byte(`{"type": "person", "data":{"id": 12423434, "Name": "Fernando"}}`)
Una versión modificada de su ejemplo en Playground: http://play.golang.org/p/85s130Sthu
Edit2:
Si la estructura de su valor JSON se basa en el nombre de un par nombre / valor, puede hacer lo mismo con a:
type Container map[string]json.RawMessage
Estaba organizando un JSONs impropio usando Golang y cuando quiero hacerlo con campos numéricos, Golang lo transforma en números flotantes en lugar de usar números largos, por ejemplo.
Tengo el siguiente JSON:
{
"id": 12423434,
"Name": "Fernando"
}
Después de ordenarlo en un mapa y volver a formar una cadena json, obtengo:
{
"id":1.2423434e+07,
"Name":"Fernando"
}
Como puede ver, el campo "id" está en notación de coma flotante.
El código que estoy usando es el siguiente:
package main
import (
"encoding/json"
"fmt"
"os"
)
func main() {
//Create the Json string
var b = []byte(`
{
"id": 12423434,
"Name": "Fernando"
}
`)
//Marshal the json to a map
var f interface{}
json.Unmarshal(b, &f)
m := f.(map[string]interface{})
//print the map
fmt.Println(m)
//unmarshal the map to json
result,_:= json.Marshal(m)
//print the json
os.Stdout.Write(result)
}
Imprime: mapa [id: 1.2423434e + 07 Nombre: Fernando] {"Nombre": "Fernando", "id": 1.2423434e + 07}
Parece ser que el primer mariscal del mapa genera el FP. ¿Cómo puedo arreglarlo por mucho tiempo?
Este es el enlace al programa en el patio de juegos de goland: http://play.golang.org/p/RRJ6uU4Uw-
Fer
Hay momentos en los que no se puede definir una estructura de antemano, pero aún así se requieren números para pasar sin cambios el proceso mariscal-unmarshal.
En ese caso, puede usar el método UseNumber en json.Decoder, que causa que todos los números se desemparejen como json.Number (que es solo la representación de cadena original del número). Esto también puede ser útil para almacenar enteros muy grandes en JSON.
Por ejemplo:
package main
import (
"strings"
"encoding/json"
"fmt"
"log"
)
var data = `{
"id": 12423434,
"Name": "Fernando"
}`
func main() {
d := json.NewDecoder(strings.NewReader(data))
d.UseNumber()
var x interface{}
if err := d.Decode(&x); err != nil {
log.Fatal(err)
}
fmt.Printf("decoded to %#v/n", x)
result, err := json.Marshal(x)
if err != nil {
log.Fatal(err)
}
fmt.Printf("encoded to %s/n", result)
}
Resultado:
decoded to map[string]interface {}{"id":"12423434", "Name":"Fernando"}
encoded to {"Name":"Fernando","id":12423434}