Procesamiento JSON con Go

Los fundamentos de la ordenación y desglose de JSON

JSON significaJavaScriptNotación de objetos, y es una forma muy práctica de intercambiar datos estructurados. Y es muy popular, especialmente cuando interactúa con API.

Go tiene soporte de nivel superior para JSON en su biblioteca estándar, conlaencoding/jsonpaquete.

En comparación con los lenguajes de tipo impreciso, la decodificación de JSON es más complicada. En JavaScript, todo lo que necesita hacer esJSON.parse(). Python tienejson.loads()y PHP tienejson_decode(). Simplemente descargan valores sin problemas, pero al ser Go fuertemente tipado, necesita hacer un poco más de trabajo para hacer coincidir los tipos.

JSON tiene 3 tipos básicos:booleanos,números,instrumentos de cuerda, combinado usandomatricesyobjetospara construir estructuras complejas.

Las llamadas de terminología de Gomariscalel proceso de generar una cadena JSON a partir de una estructura de datos, ydesarmarel acto de analizar JSON en una estructura de datos.

Una cadena JSON

input := `{"firstname": "Bill", "surname": "Gates"}`

Unmarshal JSON

Aquí hay un ejemplo JSON tomado deMDN de Mozilla

{
  "squadName": "Super hero squad",
  "homeTown": "Metro City",
  "formed": 2016,
  "secretBase": "Super tower",
  "active": true,
  "members": [
    {
      "name": "Molecule Man",
      "age": 29,
      "secretIdentity": "Dan Jukes",
      "powers": [
        "Radiation resistance",
        "Turning tiny",
        "Radiation blast"
      ]
    },
    {
      "name": "Madame Uppercut",
      "age": 39,
      "secretIdentity": "Jane Wilson",
      "powers": [
        "Million tonne punch",
        "Damage resistance",
        "Superhuman reflexes"
      ]
    },
    {
      "name": "Eternal Flame",
      "age": 1000000,
      "secretIdentity": "Unknown",
      "powers": [
        "Immortality",
        "Heat Immunity",
        "Inferno",
        "Teleportation",
        "Interdimensional travel"
      ]
    }
  ]
}

¿Cómo podemos analizarlo en una estructura de datos de Go? Necesitamos una estructura de datos coincidente, por supuesto. Tenemos 5 tipos básicos y una variedad de objetos. Comencemos con los tipos básicos:

type squad struct {
    SquadName string
    HomeTown string
    Formed int
    SecretBase string
    Active bool
}

Necesitamos definir el JSON como un[]byte, como esto:

input := []byte(`
    {
        "squadName": "Super hero squad",
        [...]
    }
`)

Y podemos desarmar el JSON a una instancia de escuadrón:

s := squad{}
err := json.Unmarshal(input, &s)
if err != nil {
    panic(err)
}
fmt.Printf("%v", s)

Esto imprimirá

{Super hero squad Metro City 2016 Super tower true}

tocar

Observe cómo no tenemos ningún error al quejarnos de la coincidencia faltante entre los valores JSON y nuestra estructura, se ignoran.

Asegurémonos de que json.Unmarshal () nos obtenga todos los campos, con:

type squad struct {
	SquadName  string
	HomeTown   string
	Formed     int
	SecretBase string
	Active     bool
	Members    []Member
}

type Member struct { Name string Age int SecretIdentity string Powers []string }

tocar

Recuerde tener propiedades públicas (mayúsculas) en sus estructuras.

Cambiar el nombre de los campos JSON

En este caso, todo estuvo bien porque el JSON tenía nombres de archivo compatibles. ¿Qué pasa si desea mapear el JSON a otros campos en su estructura?

Por ejemplo, ¿qué pasa si el nombre del miembro se pasa comomember_name, pero quieres que se almacene enName¿en lugar de?

Utilice esta sintaxis:

type Member struct {
	Name string `json:"member_name"`
}

Ignorar los campos JSON

Utilice esta sintaxis:

type Member struct {
	Name string `json:"-"`
}

y el campo Nombre se ignorará al calcular / deshacer.

Conversión de tipos de campo JSON

Puede usar etiquetas para anotar el tipo al que se convertirá el JSON:

type Member struct {
    Age       int `json:"age,string"`
}

La estructura de miembro tiene unAgepropiedad que se representa como unaint. ¿Y si quieres que sea unstringen su lugar, pero JSON pasa unint?

Utilice la anotación de tipo:

type Member struct {
    Age       json.Number `json:"age,Number"`
}

El tipo de número es un alias parastring.

Obtenga más información sobre las etiquetas enExplicación de las etiquetas Go

Mariscal JSON

Es posible que ahora queramos construir una cadena JSON a partir de nuestras estructuras de datos. Por ejemplo, este podría ser un programa que toma un código de país y devuelve los detalles del país correspondiente en formato JSON.

package main

import ( “encoding/json” “fmt” )

type country struct { Name string }

func main() { country_code := “US”

<span style="color:#a6e22e">the_country</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">country</span>{}

<span style="color:#66d9ef">switch</span> <span style="color:#a6e22e">country_code</span> {
<span style="color:#66d9ef">case</span> <span style="color:#e6db74">"US"</span>:
	<span style="color:#a6e22e">the_country</span>.<span style="color:#a6e22e">Name</span> = <span style="color:#e6db74">"United States"</span>
}

<span style="color:#a6e22e">c</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">json</span>.<span style="color:#a6e22e">Marshal</span>(<span style="color:#a6e22e">the_country</span>)
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
	panic(<span style="color:#a6e22e">err</span>)
}

<span style="color:#75715e">// c is now a []byte containing the encoded JSON

fmt.Print(string(c)) }

tocar

Cuando se ejecuta, este programa imprimirá{"Name":"United States"}.

json.Marshal()devuelve un[]byte, por lo que debemos convertirlo en una cadena al pasarlo afmt.Print(), de lo contrario, verá una lista de números aparentemente sin sentido (pero son significativos, ya que son los bytes reales que componen la cadena).

json.Marshal()procesará correctamente tipos básicos y compuestos como cortes y mapas.

Leer más

Leer másen el blog de Goy enlaencoding/jsonpaquete doc


Más tutoriales de go: