如何根据条件将任何数据类型编组为字符串并从字符串解组为特定数据类型

问题描述

type State struct {
    Type      string    `json:"type" validate:"required"`
    Value     string    `json:"value"`
}

我有一个这样的结构。我需要将状态以不同类型传递给 API。

例如:状态可以是{ type : 'boolean',value: true }{ type : 'string',value: 'ABC' }

我将它()作为字符串存储在数据库中。

然后,当我从 API 传递时,我需要考虑类型(而不是字符串)来设置特定值。

{ type : 'boolean',value: true }{ type : 'string',value: 'ABC' }

如何使用编组和解组来实现这一点?

解决方法

您可以在代码中定义编组和解组逻辑。

type State struct {
    Type  string      `json:"type" validate:"required"`
    Value interface{} `json:"value"`
}

func (s *State) UnmarshalJSON(b []byte) (err error) {
    tmpMap := map[string]string{}
    err = json.Unmarshal(b,&tmpMap)
    if err != nil {
        return err
    }
    if tmpMap["type"] == "" {
        return errors.New("type not present")
    }
    if tmpMap["value"] == "" {
        return errors.New("value not present")
    }
    if tmpMap["type"] == "string" {
        s.Type = "string"
        s.Value = tmpMap["value"]
    } else if tmpMap["type"] == "boolean" {
        s.Type = "boolean"
        s.Value = tmpMap["value"] == "true"
    } else {
        //TODO implements other type
        return errors.New(fmt.Sprintf("Unknown type %s",tmpMap["type"]))
    }
    return nil
}

https://play.golang.org/p/BnD7HAuURzJ

同样,您可以在 MarshalJSON 结构体上定义 State 方法来处理数据序列化。

func (c State) MarshalJSON() ([]byte,error)

要将 State db 存储在 db 中的单列中,您可以实现

func (c State) Value() (driver.Value,error)

要从 DB 列构建状态,您需要将 Scan 方法实现为

func (e *State) Scan(value interface{}) error