douwei1904 2018-05-05 08:22
浏览 61
已采纳

元数据/非元数据int类型

I use an int type to represent an enum. I want to convert it to string when I marshal it to JSON, AFAIK, I should implement UnmarshalJSON and MarshalJSON, but it complains:

marshal error: json: error calling MarshalJSON for type main.trxStatus: invalid character 'b' looking for beginning of valueunexpected end of JSON input

when marshalling. Then I've add the quotes to the marshalled string:

func (s trxStatus) MarshalJSON() ([]byte, error) {
    return []byte("\"" + s.String() + "\""), nil
}

the Marshal works now but it can't Unmarshal from the marshalled byte stream correctly.

package main

import (
    "encoding/json"
    "fmt"
)

type trxStatus int

type test struct {
    S trxStatus
    A string
}

const (
    buySubmitted trxStatus = iota
    buyFilled
    sellSubmiited
    sellFilled
    finished
)

var ss = [...]string{"buySubmitted", "buyFilled", "sellSubmiited", "sellFilled", "Finished"}

func (s *trxStatus) UnmarshalJSON(bytes []byte) error {
    status := string(bytes)
    // unknown
    for i, v := range ss {
        if v == status {
            tttt := trxStatus(i)
            *s = tttt
            break
        }
    }
    return nil
}

func (s trxStatus) MarshalJSON() ([]byte, error) {
    return []byte(s.String()), nil
}

func (s trxStatus) String() string {

    if s < buySubmitted || s > finished {
        return "Unknown"
    }

    return ss[s]
}

func main() {
    s := test{S: buyFilled, A: "hello"}
    j, err := json.Marshal(s)
    if err != nil {
        fmt.Printf("marshal error: %v", err)
    }
    var tt test
    fmt.Println(json.Unmarshal(j, &tt))
    fmt.Println(tt)
}
  • 写回答

1条回答 默认 最新

  • dpzbzp8728 2018-05-05 09:01
    关注

    When writing your custom Marshaler and Unmarshaler implementations make sure to include or trim the surrounding double quotes of json strings.

    func (s *trxStatus) UnmarshalJSON(bytes []byte) error {
        status := string(bytes)
        if n := len(status); n > 1 && status[0] == '"' && status[n-1] == '"' {
            status = status[1:n-1] // trim surrounding quotes
        }
        // unknown
        for i, v := range ss {
            if v == status {
                tttt := trxStatus(i)
                *s = tttt
                break
            }
        }
        return nil
    }
    
    func (s trxStatus) MarshalJSON() ([]byte, error) {
        return []byte(`"` + s.String() + `"`), nil
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥20 测距传感器数据手册i2c