为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Go 中解组可以是数组或字符串的字段?

如何在 Go 中解组可以是数组或字符串的字段?

Go
慕运维8079593 2023-06-19 17:21:19
我正在尝试解组此文件:{  "@babel/code-frame@7.0.0": {    "licenses": "MIT",    "repository": "https://github.com/babel/babel/tree/master/packages/babel-code-frame",    "publisher": "Sebastian McKenzie",    "email": "sebmck@gmail.com",    "path": "/Users/lislab/workspace/falcon-enrolment/frontend-customer/node_modules/@babel/code-frame",    "licenseFile": "/Users/lislab/workspace/falcon-enrolment/frontend-customer/node_modules/@babel/code-frame/LICENSE"  },  "json-schema@0.2.3": {    "licenses": [      "AFLv2.1",      "BSD"    ],    "repository": "https://github.com/kriszyp/json-schema",    "publisher": "Kris Zyp",    "path": "/Users/lislab/workspace/falcon-enrolment/frontend-customer/node_modules/json-schema",    "licenseFile": "/Users/lislab/workspace/falcon-enrolment/frontend-customer/node_modules/json-schema/README.md"  }}进入这个结构:type Dependency struct {    Name    string    URL     string    Version string    License string}使用这些说明:dependencies := map[string]*json.RawMessage{}err = json.Unmarshal(file, &dependencies)// boilerplatefor key, value := range dependencies {    depVal := map[string]string{}    err = json.Unmarshal(*value, &depVal)    // boilerplate    result = append(result, depVal)}这个问题是在“json-schema@0.2.3”中我们有一组许可证而不是一个字符串,因此我显然得到了json: cannot unmarshal array into Go value of type string 有没有办法自动处理license可以是数组或字符串的字段?
查看完整描述

1 回答

?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

不幸的是,该软件包没有为此提供真正的自动解决方案json。


但是您可以将依赖项解组为 amap[string]*json.RawMessage而不是map[string]string. json.RawMessage只是一个[]byte,因此您可以根据第一个字节来决定消息的类型。


例子:


for _, value := range dependencies {

    depVal := map[string]*json.RawMessage{}


    _ = json.Unmarshal(*value, &depVal)


    // check if the first character of the RawMessage is a bracket

    if rune([]byte(*depVal["licenses"])[0]) == '[' {

        var licenses []string

        json.Unmarshal(*depVal["licenses"], &licenses)

        fmt.Println(licenses)

        // do something with the array

    }


    result = append(result, Dependency{

        URL:     string(*depVal["repository"]),

        License: string(*depVal["licenses"]),

    })

}

另一种解决方案是使用 2 个结构。一个包含字符串形式的依赖项,另一个包含数组形式的依赖项。然后您可以尝试json.Unmarshal同时调用它们。例子:



type Dependency struct {

    Licenses string

    // other fields

}


type DependencyWithArr struct {

    Licenses []string

    // other fields

}


// in your function

for _, value := range dependencies {

    type1 := Dependency{}

    type2 := DependencyWithArr{}


    err = json.Unmarshal(*value, &type1)

    if err != nil {

        err = json.Unmarshal(*value, &type2)

        // use the array type

    } else {

        // use the single string type

    }

}


查看完整回答
反对 回复 2023-06-19
  • 1 回答
  • 0 关注
  • 101 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信