Home > Backend Development > Golang > How to Implement UnmarshalJSON for Derived Scalar Types in Go?

How to Implement UnmarshalJSON for Derived Scalar Types in Go?

Patricia Arquette
Release: 2024-11-26 18:41:16
Original
480 people have browsed it

How to Implement UnmarshalJSON for Derived Scalar Types in Go?

UnmarshalJSON Implementation for Derived Scalars in Go

Problem:
A custom type that converts subtyped integer constants to strings and vice versa requires automatic unmarshalling of JSON strings. This is challenging because UnmarshalJSON does not provide a way to modify the scalar value without using a struct.

Solution:
To implement UnmarshalJSON for a derived scalar type, consider the following steps:

Use a Pointer Receiver:
Use a pointer receiver for the UnmarshalJSON method to modify the value of the receiver.

Unmarshal to a String:
Unmarshal the JSON text into a plain string, removing all JSON quoting.

Lookup and Set Value:
Use the Lookup function to retrieve the corresponding PersonID based on the string value. Assign the result to the receiver.

Example:

func (intValue *PersonID) UnmarshalJSON(data []byte) error {
  var s string
  if err := json.Unmarshal(data, &s); err != nil {
    return err
  }
  *intValue = Lookup(s)
  return nil
}
Copy after login

Code Example:

package main

import (
    "encoding/json"
    "fmt"
)

type PersonID int

const (
    Bob PersonID = iota
    Jane
    Ralph
    Nobody = -1
)

var nameMap = map[string]PersonID{
    "Bob":    Bob,
    "Jane":   Jane,
    "Ralph":  Ralph,
    "Nobody": Nobody,
}

var idMap = map[PersonID]string{
    Bob:    "Bob",
    Jane:   "Jane",
    Ralph:  "Ralph",
    Nobody: "Nobody",
}

func (intValue PersonID) Name() string {
    return idMap[intValue]
}

func Lookup(name string) PersonID {
    return nameMap[name]
}

func (intValue *PersonID) UnmarshalJSON(data []byte) error {
  var s string
  if err := json.Unmarshal(data, &s); err != nil {
    return err
  }
  *intValue = Lookup(s)
  return nil
}

type MyType struct {
    Person   PersonID `json: "person"`
    Count    int      `json: "count"`
    Greeting string   `json: "greeting"`
}

func main() {
    var m MyType
    if err := json.Unmarshal([]byte(`{"person": "Ralph", "count": 4, "greeting": "Hello"}`), &m); err != nil {
        fmt.Println(err)
    } else {
        for i := 0; i < m.Count; i++ {
            fmt.Println(m.Greeting, m.Person.Name())
        }
    }
}
Copy after login

Output:

Hello Ralph
Hello Ralph
Hello Ralph
Hello Ralph
Copy after login

The above is the detailed content of How to Implement UnmarshalJSON for Derived Scalar Types in Go?. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template