如何通过Unmarshal到泛型接口验证JSON及字节数组的有效性?
解决JSON有效性验证的泛型兼容问题
你的问题很典型——原来的验证逻辑只针对JSON对象(键值对结构),所以数组这类合法JSON会被误判。其实只要把目标类型换成interface{},就能兼容所有合法的JSON结构,包括对象、数组、单个基础类型值。
修正后的代码
package main import ( "encoding/json" "fmt" ) func isJSON(s string) bool { var js interface{} // 用空接口接受任意JSON类型 return json.Unmarshal([]byte(s), &js) == nil } func main() { var tests = []string{ `{"a":"b"}`, // JSON对象 `[{"a":"b"},{"a":"b"}]`, // JSON数组 `"hello world"`, // 字符串类型JSON `123`, // 数字类型JSON `true`, // 布尔类型JSON `null`, // null值JSON } for _, t := range tests { fmt.Printf("isJSON(%q) = %v\n", t, isJSON(t)) } }
为什么这样能解决问题?
interface{}是Go的空接口,可以接收任意类型的值,JSON反序列化时会根据输入自动映射成对应的Go类型:- JSON对象 →
map[string]interface{} - JSON数组 →
[]interface{} - 字符串 →
string - 数字 →
float64(整数也会转成float64) - 布尔值 →
bool - null →
nil
- JSON对象 →
- 只要输入的字符串是语法合法的JSON,
json.Unmarshal就会返回nil,这样就能准确判断有效性。
测试结果运行后会输出:
isJSON("{\"a\":\"b\"}") = true isJSON("[{\"a\":\"b\"},{\"a\":\"b\"}]") = true isJSON("\"hello world\"") = true isJSON("123") = true isJSON("true") = true isJSON("null") = true
这样不管是数组还是其他合法JSON类型,都能被正确识别为有效JSON了。
内容的提问来源于stack exchange,提问作者fabfas
相关产品推荐
相关产品推荐

