代码之家  ›  专栏  ›  技术社区  ›  jfly

封送/解封送整型

  •  0
  • jfly  · 技术社区  · 8 年前

    我使用 int 键入以表示枚举。当我将其封送为JSON时,我想将其转换为字符串,AFAIK,我应该实现 UnmarshalJSON MarshalJSON ,但它抱怨:

    封送处理错误:json:为类型调用MarshalJSON时出错 主要的trxStatus:查找的开头字符“b”无效 值JSON输入意外结束

    编组时。然后,我将引号添加到编组字符串中:

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

    这个 Marshal 现在可以了,但不行 Unmarshal 正确地从封送的字节流。

    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 回复  |  直到 8 年前
        1
  •  1
  •   mkopriva    8 年前

    在编写自定义封送拆收器和反封送拆收器实现时,请确保包含或修剪json字符串周围的双引号。

    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
    }