Personalizar la separación de JSON con Reflection
En Go, desarmar JSON en una estructura es un proceso sencillo. Sin embargo, cuando se trata de campos que tienen etiquetas personalizadas, como json:"some_field", el mecanismo de clasificación estándar puede no ser suficiente.
Un método para manejar este escenario es utilizar la reflexión. Al inspeccionar los campos de la estructura usando la reflexión, podemos verificar si un campo tiene una etiqueta específica y, de ser así, manejar su clasificación en consecuencia.
En este caso particular, queremos asegurarnos de que un campo con la etiqueta json sea descompuesto en un campo de cadena tal como está. Esto nos permite manejar objetos o matrices JSON dentro de nuestra estructura Go.
Escenario de ejemplo
Considere los siguientes datos JSON y la estructura Go:
{
"I": 3,
"S": {
"phone": {
"sales": "2223334444"
}
}
}
type A struct {
I int64
S string `sql:"type:json"`
}
Nuestro objetivo es descomponer el campo "S" como una cadena, preservando su estructura JSON anidada.
Solución usando Reflection
Lo siguiente El código demuestra cómo lograr esto usando la reflexión:
func main() {
a := A{}
// Unmarshal the JSON data into a byte slice
var data []byte
// Iterate over the fields of the struct
typ := reflect.TypeOf(a)
val := reflect.ValueOf(a)
for i := 0; i En este enfoque, inspeccionamos manualmente cada campo de la estructura usando la reflexión para determinar si tiene la etiqueta "json". Si es así, desglosamos los datos JSON en el campo como una cadena.
Solución alternativa con Custom Marshaler y Unmarshaler
Otra opción es implementar un tipo personalizado, como RawString, que implementa las interfaces json.Marshaler y json.Unmarshaler. Esto permite una mayor flexibilidad y control sobre el proceso de organización.
Este enfoque se demuestra en el siguiente código:
// RawString is a raw encoded JSON object.
// It implements Marshaler and Unmarshaler and can
// be used to delay JSON decoding or precompute a JSON encoding.
type RawString string
// MarshalJSON returns *m as the JSON encoding of m.
func (m *RawString) MarshalJSON() ([]byte, error) {
return []byte(*m), nil
}
// UnmarshalJSON sets *m to a copy of data.
func (m *RawString) UnmarshalJSON(data []byte) error {
if m == nil {
return errors.New("RawString: UnmarshalJSON on nil pointer")
}
*m = RawString(data)
return nil
}
const data = `{"i":3, "S":{"phone": {"sales": "2223334444"}}}`
type A struct {
I int64
S RawString `sql:"type:json"`
}
func main() {
a := A{}
err := json.Unmarshal([]byte(data), &a)
if err != nil {
log.Fatal("Unmarshal failed", err)
}
fmt.Println("Done", a)
}
Al implementar nuestro propio tipo, podemos personalizar el proceso de descomposición y evitar la necesidad de reflexión, lo que da como resultado una solución más limpia y eficiente.
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3