拉风的咖菲猫
[...]尝试仅访问一个字段(在众多可用字段中)。对于这个具体的用例,我将使用一个库来查询和访问已知路径中的单个值,例如:https://github.com/jmespath/go-jmespath另一方面,如果您正在练习如何访问JSON中的嵌套值,我建议您尝试编写一个递归函数,该函数以与go-jmespath相同(但简单)的方式遵循未知结构中的路径。好吧,我挑战了自己,花了一个小时写这篇文章。它的工作原理。不确定性能或错误,它真的很有限:)https://play.golang.org/p/dlIsmG6Lk-ppackage mainimport ( "encoding/json" "errors" "fmt" "strings")func main() { // I Just added a bit more of data to the structure to be able to test different paths fileContent := []byte(` {"results": [ {"times": [ 1, 2, 3, 4 ]}, {"times2": [ 5, 6, 7, 8 ]}, {"username": "rosadabril"}, {"age": 42}, {"location": [41.5933262, 1.8376757]} ], "more_results": { "nested_1": { "nested_2":{ "foo": "bar" } } } }`) var content map[string]interface{} if err := json.Unmarshal(fileContent, &content); err != nil { panic(err) } // some paths to test valuePaths := []string{ "results.times", "results.times2", "results.username", "results.age", "results.doesnotexist", "more_results.nested_1.nested_2.foo", } for _, p := range valuePaths { breadcrumbs := strings.Split(p, ".") value, err := search(breadcrumbs, content) if err != nil { fmt.Printf("\nerror searching '%s': %s\n", p, err) continue } fmt.Printf("\nFOUND A VALUE IN: %s\n", p) fmt.Printf("Type: %T\nValue: %#v\n", value, value) }}// search is our fantastic recursive function! The idea is to search in the structure in a very basic way, for complex querying use jmespathfunc search(breadcrumbs []string, content map[string]interface{}) (interface{}, error) { // we should never hit this point, but better safe than sorry and we could incurr in an out of range error (check line 82) if len(breadcrumbs) == 0 { return nil, errors.New("ran out of breadcrumbs :'(") } // flag that indicates if we are at the end of our trip and whe should return the value without more checks lastBreadcrumb := len(breadcrumbs) == 1 // current breadcrumb is always the first element. currentBreadcrumb := breadcrumbs[0] if value, found := content[currentBreadcrumb]; found { if lastBreadcrumb { return value, nil } // if the value is a map[string]interface{}, go down the rabbit hole, recursion! if aMap, isAMap := value.(map[string]interface{}); isAMap { // we are calling ourselves popping the first breadcrumb and passing the current map return search(breadcrumbs[1:], aMap) } // if it's an array of interfaces the thing gets complicated :( if anArray, isArray := value.([]interface{}); isArray { for _, something := range anArray { if aMap, isAMap := something.(map[string]interface{}); isAMap && len(breadcrumbs) > 1 { if v, err := search(breadcrumbs[1:], aMap); err == nil { return v, nil } } } } } return nil, errors.New("woops, nothing here")}