[["my",257.14,257.24],["txt", 121.11, 65.555]]
来自一个经过解组的结构 - 而且我没有这样做。
以下是我的尝试:
x := []MyStruct{{Zero: map[int]string{0: "str"}, One: map[int]float32{1: 5.6}, Two: map[int]float32{1: 5.88}}}
MyStruct在哪里:
type Timestamp struct {
Zero map[int]string `json:"0"`
One map[int]float32 `json:"1"`
Two map[int]float32 `json:"2"`
}
这会产生错误的json结构:
"myStruct":[{"0":{"0":"has"},"1":{"1":5.6},"2":{"1":5.88}}]
还尝试this
正确方向的任何线索都将受到高度赞赏。
答案 0 :(得分:3)
也许这是你的期望。可以实现自定义MarshalJSON / UnmarshalJSON。
package main
import (
"encoding/json"
"errors"
"fmt"
"log"
)
type Timestamp struct {
Zero []string
One []float32
Two []float32
}
func (t *Timestamp) UnmarshalJSON(b []byte) error {
var arr [][3]interface{}
err := json.Unmarshal(b, &arr)
if err != nil {
return nil
}
t.Zero = nil
t.One = nil
t.Two = nil
for _, v := range arr {
if len(v) != 3 {
return errors.New("invalid json")
}
if s, ok := v[0].(string); ok {
t.Zero = append(t.Zero, s)
}
if f, ok := v[1].(float64); ok {
t.One = append(t.One, float32(f))
}
if f, ok := v[2].(float64); ok {
t.Two = append(t.Two, float32(f))
}
}
return nil
}
func (t *Timestamp) MarshalJSON() ([]byte, error) {
var arr [][3]interface{}
var max int
if max < len(t.Zero) {
max = len(t.Zero)
}
if max < len(t.One) {
max = len(t.One)
}
if max < len(t.Two) {
max = len(t.Two)
}
for i := 0; i < max; i++ {
var v [3]interface{}
if i < len(t.Zero) {
v[0] = t.Zero[i]
}
if i < len(t.One) {
v[1] = t.One[i]
}
if i < len(t.Two) {
v[2] = t.Two[i]
}
arr = append(arr, v)
}
return json.Marshal(arr)
}
const j = `[["my",257.14,257.24],["txt", 121.11, 65.555]]`
func main() {
var ts Timestamp
err := json.Unmarshal([]byte(j), &ts)
if err != nil {
log.Fatal(err)
}
b, err := json.Marshal(&ts)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b))
}
答案 1 :(得分:2)
您遇到的问题是您正在尝试解组地图,而地图会与JSON对象相关联。您所需的输出是一个列表,因此您需要解组数组或切片以获取列表作为您的值。
尝试制作适配器。
小例子:
type Object struct {
Base float32
Radius float32
Height float32
X float32
Y float32
}
func (obj *Object) ToCircle() *Circle {
return &Circle{
Radius: obj.Radius,
X: obj.X,
Y: obj.Y,
}
}
func (obj *Object) ToRectangle() *Rectangle {
return &Rectangle{
Base: obj.Base,
Height: obj.Height,
X: obj.X,
Y: obj.Y,
}
}
在上面的示例中,Object
分别使用Rectangle
和Circle
适配器转换为ToRectangle()
或ToCircle()
。在您的情况下,您需要将Timestamp
转换为[]interface{}
。然后你可以解组,你只需要得到该切片中任何值的列表,在这种情况下,这是你想要的输出。
对于intsance,签名如果您的适配器看起来像这样:
func (t *Timestamp) ToFoo() []interface{} {
var ret []interface{}
// Do some stuff to take values of 't' and append to 'ret'
return ret
}
func main() {
var result []interface{}
json.Unmarshal(t.ToFoo(), &result)
// ...
}
我将为您留下实施细节。