我正试图解组该文件:
{ "@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可以是数组或字符串的字段?
license
谢谢
不幸的是,json软件包没有提供真正的自动解决方案。
json
但是您可以将依赖项解组为a map[string]*json.RawMessage而不是map[string]string。json.RawMessage只是一个[]byte,因此您可以根据第一个字节确定消息的类型。
map[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它们。例:
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 } }