Go语言解析自定义类型JSON数组失败,请求排查错误
Go JSON解析问题:Schema为空的原因与修复
错误原因分析
- 你的JSON结构是数组,每个元素是仅含单个键的对象(键为表名,值为列信息数组),但你定义的
Schema结构体多了一层Schema字段,JSON中不存在这个层级的key,导致解析时无法匹配数据,最终字段为空。 - 你声明的
var schemas []Schema期望每个数组元素对应一个Schema实例,但Schema结构体里的Schema字段在JSON中无对应项,自然无法填充内容。
修复方案
以下两种方式均可解决问题:
方式一:直接解析为[]map[string][]ColumnType
无需额外定义Schema结构体,直接将JSON数组解析为切片,每个元素是表名到列数组的映射:
package main import ( "encoding/json" "io" "log" "os" ) type ColumnType struct { Name string `json:"name"` Type string `json:"type"` } func main() { mocksSchemas, err := os.Open("parse_config/mock_schema.json") if err != nil { log.Fatal("Error opening mock file: ", err) } defer mocksSchemas.Close() // defer放在文件打开成功后,避免空指针 content, err := io.ReadAll(mocksSchemas) if err != nil { log.Fatal("Error reading mock file: ", err) } var schemas []map[string][]ColumnType err = json.Unmarshal(content, &schemas) if err != nil { log.Fatal("Error during Unmarshal(): ", err) } // 测试输出解析结果 for _, tableMap := range schemas { for tableName, columns := range tableMap { log.Printf("表名: %s", tableName) for _, col := range columns { log.Printf(" 列名: %s, 类型: %s", col.Name, col.Type) } } } }
方式二:调整结构体定义(保留自定义结构)
如果希望用结构体包裹表信息,可以通过遍历map填充自定义结构体:
package main import ( "encoding/json" "io" "log" "os" ) type ColumnType struct { Name string `json:"name"` Type string `json:"type"` } // 自定义表结构结构体 type TableSchema struct { TableName string `json:"-"` // 忽略JSON标签,因为表名是动态键 Columns []ColumnType } func main() { mocksSchemas, err := os.Open("parse_config/mock_schema.json") if err != nil { log.Fatal("Error opening mock file: ", err) } defer mocksSchemas.Close() content, err := io.ReadAll(mocksSchemas) if err != nil { log.Fatal("Error reading mock file: ", err) } // 先解析为原始map格式 var rawSchemas []map[string][]ColumnType err = json.Unmarshal(content, &rawSchemas) if err != nil { log.Fatal("Error during Unmarshal(): ", err) } // 转换为自定义结构体切片 var schemas []TableSchema for _, m := range rawSchemas { for tableName, cols := range m { schemas = append(schemas, TableSchema{ TableName: tableName, Columns: cols, }) } } // 测试输出 for _, s := range schemas { log.Printf("表: %s", s.TableName) for _, col := range s.Columns { log.Printf(" %s: %s", col.Name, col.Type) } } }
额外注意事项
- 你提供的JSON中存在多余的尾逗号(比如
{ "name": "col2", "type": "int"},),严格JSON解析会报错,需删除这些尾逗号。 defer mocksSchemas.Close()必须放在os.Open成功之后,避免文件打开失败时调用Close空指针。
内容的提问来源于stack exchange,提问作者Chen Kastner
相关产品推荐
相关产品推荐

