Go语言JSON反序列化Filter数组报错:无效字符','问题求助
Let's break down your problem step by step, since that JSON parsing error is pointing to a fundamental issue with your input structure.
1. The Root Cause: Invalid JSON Format
Your input JSON has a critical mistake in the filter field. Right now, you're wrapping the entire array of filter conditions in a single string with unescaped quotes, which makes the JSON completely invalid.
Original (Broken) Input Snippet:
"data": { "filter": [ "["EQ","foo",0],["LIKE","baz","%.2%"],["IN","bar",[1,5,9,11]],["EQ","myBool",true]" ], "limit": [ "101" ], "offset": [ "0" ], "sort": [ "id:ASC" ] }
Corrected Valid JSON:
The filter field should be an array of arrays (not a string containing arrays). Remove the outer quotes around the filter conditions, and ensure proper JSON syntax:
"data": { "filter": [ ["EQ","foo",0], ["LIKE","baz","%.2%"], ["IN","bar",[1,5,9,11]], ["EQ","myBool",true] ], "limit": ["101"], "offset": ["0"], "sort": ["id:ASC"] }
Why the original failed? The JSON parser saw the first "["EQ","foo",0] as a complete top-level string value, then hit the , right after it — which is illegal in JSON (you can't have multiple top-level values without wrapping them in an array/object). That's exactly what the error invalid character ',' after top-level value is telling you.
2. Fixing Your Test Code
Even with valid JSON, your current parsing code has a few issues that will cause panics or incorrect behavior:
Issues in Original Code:
- Undefined variable: You're trying to append
criteriatoparsedValues, but you never declared or assigned this variable — you meantmyStuff. - Unsafe type assertions: Using
col.(string)directly will panic if the value isn't a string (e.g., if a field name is accidentally a number). - Values handling: For the
INoperator, your code will append the entire array[1,5,9,11]as a single element invalues— which is correct for yourMyStructdefinition, but you should be aware of this structure for later use.
Corrected Test Code:
type MyStruct struct { Operator string Field string Values []interface{} // Can be array of strings/int64, or a nested array for IN } func parseFilters(filters string) ([]MyStruct, error) { var parsed [][]interface{} var parsedValues []MyStruct if err := json.Unmarshal([]byte(filters), &parsed); err != nil { return nil, fmt.Errorf("failed to unmarshal filters: %w", err) } for _, condition := range parsed { var myStuff MyStruct var values []interface{} for idx, val := range condition { switch idx { case 0: op, ok := val.(string) if !ok { return nil, fmt.Errorf("invalid operator type at index %d", idx) } myStuff.Operator = op case 1: field, ok := val.(string) if !ok { return nil, fmt.Errorf("invalid field type at index %d", idx) } myStuff.Field = field default: values = append(values, val) } } myStuff.Values = values parsedValues = append(parsedValues, myStuff) } return parsedValues, nil }
Key improvements here:
- Added error handling for type mismatches to avoid panics
- Fixed the variable name typo (
criteria→myStuff) - Wrapped errors with
fmt.Errorfand%wfor better error chaining - Renamed variables for clarity (e.g.,
y→condition,col→val)
3. Quick Notes on Edge Cases
- For the
INoperator,myStuff.Valueswill contain a single element which is the array[1,5,9,11]— you'll need to handle this nested array when building your query. - The
limit,offset, andsortfields in your input are arrays of strings — you might want to unmarshal them to scalar values (e.g.,intfor limit/offset) for easier use.
内容的提问来源于stack exchange,提问作者Deslyxia

