Go语言解析字符串为JSON获取指定字段值时代码失效原因
代码无法正常运行的具体原因
- Unmarshal目标类型完全不匹配
你将接收解析结果的raw定义为map[string]string,但输入JSON的字段值包含数字(school_capacity:2000)、嵌套JSON对象(school_details),并非全是字符串值。json.Unmarshal遇到类型不匹配时会直接返回错误,而你没有捕获这个返回的错误值,程序会静默失败,raw最终是空Map。 - 取值的键名完全错误
你最后打印的是raw["input"],但解析后的JSON顶层根本不存在input这个键——你存储原始JSON字符串的变量名才叫input,实际顶层键是school_id、school_capacity这类,取raw["input"]永远只会拿到空值。
匹配你两项核心需求的实现方案
你要求的两个能力:
- 支持用键名直接取顶层字段值,类似
input['school_id']的访问形式 - 可以将
school_details字段的值转换为map[string]string类型
正确的实现逻辑为:
- 解析全量动态JSON时使用
map[string]any作为接收容器,兼容不同值类型的顶层字段 - 必须捕获
json.Unmarshal的返回错误,避免静默失败 - 单独对
school_details对应的JSON片段做二次解析,转成指定的map[string]string类型
可直接运行的示例代码:
package main import ( "encoding/json" "fmt" ) func main() { input := `{"school_capacity":2000,"school_id":"10","school_details":{"classes":"8","subjects":"5","teachers":"15"}}` // 第一层解析全量动态JSON var parsedInput map[string]any err := json.Unmarshal([]byte(input), &parsedInput) if err != nil { fmt.Printf("顶层JSON解析失败: %v\n", err) return } // 实现需求1:按键名取对应字段值 schoolID := parsedInput["school_id"] fmt.Println("获取到的school_id值:", schoolID) // 实现需求2:将school_details转为map[string]string detailJSON, err := json.Marshal(parsedInput["school_details"]) if err != nil { fmt.Printf("提取school_details原始内容失败: %v\n", err) return } var detailMap map[string]string err = json.Unmarshal(detailJSON, &detailMap) if err != nil { fmt.Printf("school_details转map[string]string失败: %v\n", err) return } fmt.Println("转换后的school_details值:", detailMap) }
补充说明:如果后续你确定JSON结构固定,也可以定义强类型结构体做解析,相比动态Map会减少不必要的类型断言,运行效率更高。
内容的提问来源于stack exchange,提问作者pep8
相关产品推荐
相关产品推荐

