正如你引用的json.Marshal() https://golang.org/pkg/encoding/json/#Marshal, the ,string
选项仅适用于特定类型,即:
“string”选项表示字段以 JSON 形式存储在 JSON 编码的字符串中。它仅适用于字符串、浮点、整数或布尔类型的字段。
您希望它与切片一起使用,但这不受json
包裹。
如果您仍然需要此功能,则必须编写自定义封送/解封逻辑。
您提出的内容有效,但过于复杂。这是因为您在切片上创建了自定义逻辑,但您只希望在切片(数组)的各个元素上使用此功能。您不想更改数组/切片(作为元素序列)的呈现或解析方式。
因此,一个更简单的解决方案是仅创建一个产生此行为的自定义“数字”类型,并且此自定义类型的切片元素将表现相同。
我们的自定义数字类型和编组/解组逻辑:
type Int64Str int64
func (i Int64Str) MarshalJSON() ([]byte, error) {
return json.Marshal(strconv.FormatInt(int64(i), 10))
}
func (i *Int64Str) UnmarshalJSON(b []byte) error {
// Try string first
var s string
if err := json.Unmarshal(b, &s); err == nil {
value, err := strconv.ParseInt(s, 10, 64)
if err != nil {
return err
}
*i = Int64Str(value)
return nil
}
// Fallback to number
return json.Unmarshal(b, (*int64)(i))
}
就这样!
使用它的类型:
type Foo struct {
Bars []Int64Str `json:"bars"`
}
以与您相同的方式进行测试会产生相同的结果。尝试一下去游乐场 https://play.golang.org/p/DuzIqx6JHJ2.