登录
首页 >  Golang >  Go问答

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

来源:Golang技术栈

时间:2023-04-15 08:31:52 423浏览 收藏

小伙伴们对Golang编程感兴趣吗?是否正在学习相关知识点?如果是,那么本文《如何在 Go 中解组可以是数组或字符串的字段?》,就很适合你,本篇文章讲解的知识点主要包括golang。在之后的文章中也会多多分享相关知识点,希望对大家的知识积累有所帮助!

问题内容

我正在尝试解组此文件:

{
  "@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)
// boilerplate

for 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可以是数组或字符串的字段?

谢谢

正确答案

不幸的是,该软件包没有为此提供真正的自动解决方案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
    }
}

今天带大家了解了golang的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~

声明:本文转载于:Golang技术栈 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>