
Redis与前端数据类型不匹配导致比较失败的解决方案
使用redigo库操作Redis时,经常遇到Redis返回值与前端值类型不一致的问题,导致比较失败。本文以一个具体案例,分析如何解决[]byte类型Redis返回值与前端字符串值比较不相等的问题。
问题描述:
开发者使用redigo库从Redis获取键为"123@qq.com"的值"8414"。前端通过c.query("code")获取验证码"8414"。直接比较Redis返回的[]byte类型值与前端字符串值,结果总是失败。即使将前端字符串转换为[]byte,比较结果依然错误。根本原因是Redis返回的是字节数组,前端获取的是字符串,两者表示方式不同。Redis返回的字节数组包含字符串的字节表示,可能包含额外字符,例如引号。
原始代码片段:
email := c.query("email")
code := c.query("code")
str, _ := gredis.get(email)
fmt.Println(str, string(str), "", []byte(code+""), code)
if string(str) != string(code) {
appg.failjson(e.error, "验证码错误")
return
}gredis.get函数返回[]byte类型,直接转换为字符串比较导致错误。
改进后的gredis.get函数:
开发者修改了gredis.get函数,加入json.Unmarshal进行解析:
// Get get a key
func Get(key string) (interface{}, error) {
conn := RedisConn.Get()
defer conn.Close()
reply, err := redis.Bytes(conn.Do("GET", key))
if err != nil {
return nil, err
}
// 代码1
var reply2 interface{}
err = json.Unmarshal(reply, &reply2)
if err != nil {
return nil, err
}
return reply2, nil
}通过json.Unmarshal将[]byte类型的Redis返回值解析为interface{}类型,解决了类型不一致的问题,确保后续比较正确。 需要注意的是,这种方法并非所有数据类型都能正确转换,例如存储的结构体数据会被解析为map[string]interface{}类型。
解决方案:
使用json.Unmarshal函数将Redis返回的[]byte数据解析成目标类型。这能将字节数组转换为字符串,避免数据表示方式差异导致的比较错误。 只有数据类型一致,才能保证比较结果正确。 如果存储在Redis中的数据是其他类型(例如数字),则需要根据实际类型进行相应的转换,而不是直接使用json.Unmarshal。 例如,如果存储的是数字,可以使用strconv.Atoi等函数进行转换。

