面试题答案
一键面试- 使用
json.Decoder
的Decode
方法并配合自定义结构体:- 定义一个与JSON数据结构对应的嵌套结构体。
- 使用
json.Decoder
的Decode
方法进行解析,这样可以在遇到错误时获取更多上下文信息。 - 对于可能失败的解析部分,可以使用
interface{}
类型来接收,然后在后续进行二次解析。
package main import ( "encoding/json" "fmt" ) type Outer struct { Inner1 Inner `json:"inner1"` Inner2 Inner `json:"inner2"` Extra interface{} `json:"extra"` } type Inner struct { Field1 string `json:"field1"` Field2 int `json:"field2"` } func main() { jsonData := []byte(`{ "inner1": { "field1": "value1", "field2": 123 }, "inner2": { "field1": "value2", "field2": "not an integer" }, "extra": "extra data" }`) var outer Outer decoder := json.NewDecoder(bytes.NewReader(jsonData)) if err := decoder.Decode(&outer); err != nil { var syntaxError *json.SyntaxError var unmarshalTypeError *json.UnmarshalTypeError switch { case errors.As(err, &syntaxError): fmt.Printf("Syntax error at byte offset %d\n", syntaxError.Offset) case errors.As(err, &unmarshalTypeError): fmt.Printf("Type error at field %q, offset %d\n", unmarshalTypeError.Field, unmarshalTypeError.Offset) default: fmt.Printf("Other error: %v\n", err) } } fmt.Printf("Inner1: %+v\n", outer.Inner1) // 尝试对extra进行二次解析 extraData, ok := outer.Extra.(string) if ok { fmt.Printf("Extra data: %s\n", extraData) } }
- 解析过程说明:
- 在上述代码中:
- 定义了
Outer
和Inner
结构体来匹配JSON数据结构。 Outer
结构体中的Extra
字段使用interface{}
类型来接收可能无法直接解析为特定类型的数据。- 使用
json.NewDecoder
创建解码器并调用Decode
方法进行解析。 - 在错误处理部分,通过
errors.As
来判断错误类型,如果是json.SyntaxError
可以获取语法错误的字节偏移量;如果是json.UnmarshalTypeError
可以获取类型错误的字段名和偏移量,从而清晰定位错误位置。 - 对于
Extra
字段,后续可以根据实际情况进行二次解析,这里简单地将其转换为string
类型并打印。这样即使部分数据(如inner2
的field2
解析失败),也能获取到inner1
和extra
的有效信息。
- 定义了
- 在上述代码中: