douliaodun9153 2018-03-04 21:02
浏览 162

在go中返回动态结构数组

Is there a way to read JSON files with different structures and cast read data to correct struct in a more dynamic way?

Structs:

type Person struct {
    Name string `json:"name,omitempty"`
    Age  int64  `json:"age,omitempty"`
}

type Pet struct {
    Name string `json:"name,omitempty"`
    Age  int64  `json:"age,omitempty"`
}

They are currently read from files with:

func ReadFileToByteArray(filepath string) ([]byte, error) {
    var err error
    err = os.MkdirAll(path.Dir(filepath), os.FileMode(0700))
    if err != nil {
        panic(err)
    }

    _, err = os.Stat(filepath)
    if err != nil {
        if os.IsNotExist(err) {
            file, err := os.Create(filepath)
            if err != nil {
                panic(err)
            }

            defer file.Close()
            file.Write([]byte("[]"))
        } else {
            panic(err)
        }
    }

    readbytes, err := ioutil.ReadFile(filepath)
    if err != nil {
        panic(err)
    }

    return readbytes, err
}

Read as casted arrays:

func GetPersonArrayFromFile(fn string) (data []Person) {
    readbytes, err := ReadFileToByteArray(fn)
    if err != nil {
        panic(err)
    }

    err = json.Unmarshal(readbytes, &data)
    if err != nil {
        log.Fatal(fmt.Sprintf("Filename: %[1]s Error: %[2]s (%[2]T)", fn, err))
        panic(err)
    }

    return data
}

func GetPetArrayFromFile(fn string) (data []Pet) {
    readbytes, err := ReadFileToByteArray(fn)
    if err != nil {
        panic(err)
    }

    err = json.Unmarshal(readbytes, &data)
    if err != nil {
        log.Fatal(fmt.Sprintf("Filename: %[1]s Error: %[2]s (%[2]T)", fn, err))
        panic(err)
    }

    return data
}

Current try (simplified):

func main() {
    personsJSON := `[{"name": "foo", "age": 22}, {"name": "bar", "age": 33}]`
    petsJSON := `[{"name": "bunny bunnieface", "age": 1}, {"name": "you there", "age": 5}]`

    var t []Person
    data := Get([]byte(personsJSON), t)

    var t2 []Pet
    data2 := Get([]byte(petsJSON), t2)

    fmt.Println("%v", data)
    fmt.Println("%v", data2)
}

// Return given type
func Get(b []byte, t []struct{}) []struct{} {
    err := json.Unmarshal(b, &t)
    if err != nil {
        panic(err)
    }
    return t
}

This gives:

cannot use t (type []Person) as type []struct {} in argument to Get

Can this be achieved as there's no generics or is there different approach?

https://play.golang.org/p/QEHEuqi92Wt

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 在获取boss直聘的聊天的时候只能获取到前40条聊天数据
    • ¥20 关于URL获取的参数,无法执行二选一查询
    • ¥15 液位控制,当液位超过高限时常开触点59闭合,直到液位低于低限时,断开
    • ¥15 marlin编译错误,如何解决?
    • ¥15 有偿四位数,节约算法和扫描算法
    • ¥15 VUE项目怎么运行,系统打不开
    • ¥50 pointpillars等目标检测算法怎么融合注意力机制
    • ¥20 Vs code Mac系统 PHP Debug调试环境配置
    • ¥60 大一项目课,微信小程序
    • ¥15 求视频摘要youtube和ovp数据集