【发布时间】:2018-10-15 16:09:25
【问题描述】:
我使用int 类型来表示枚举。当我将其编组为 JSON、AFAIK 时,我想将其转换为字符串,我应该实现 UnmarshalJSON 和 MarshalJSON,但它抱怨:
marshal 错误:json:错误调用 MarshalJSON 的类型 main.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.检查 json.Marshal 的错误,2. 导出测试的字段,否则封送将不起作用。 3. 您的 MarshalJSON 不返回 json 字符串,即缺少引号。 4.woking example
-
@mkopriva 感谢您的提示,请参阅我的编辑。
-
这是更新评论中提到的缺失引号。
-
我已经添加了引号,但是 Unmarshal 不起作用
-
请注意,手动构建 JSON 字符串通常是有风险的,因为转义很棘手。 MarshalJSON 的更健壮的实现是
return json.Marshal(s.String())。
标签: json go marshalling