使用 pg.Array 时如何将 reflect.Pointer() 转换为 []string?
How to convert reflect.Pointer() to []string when using pg.Array?
我正在使用 go-pg 编写自定义查询缓存系统,该系统采用传递给查询函数的查询参数并生成用于 Redis 的哈希键。我正在使用 Go 的反射来检查有效的参数类型,直到我使用 pg.Array 作为传递的参数。
Reflect 给了我 reflect.Ptr,但是我如何在调用 switch case 块时提取指针的 struct/Array?
func GenerateQueryCacheKey(args ...interface{}) string {
var argumentString = ""
for _, arg := range args {
v := reflect.ValueOf(arg)
switch v.Kind() {
case reflect.Array, reflect.Slice:
ret := make([]interface{}, v.Len())
for i := 0; i < v.Len(); i++ {
ret[i] = v.Index(i).Interface()
}
GenerateQueryCacheKey(ret...)
case reflect.Bool:
argumentString += strconv.FormatBool(v.Bool())
case reflect.String:
argumentString += v.String()
case reflect.Int:
argumentString += string(v.Int())
case reflect.Uint:
argumentString += string(v.Uint())
case reflect.Float32:
argumentString += strconv.FormatFloat(v.Float(), 'E', -1, 32)
case reflect.Invalid:
log.Printf("Invalid type handle! " + fmt.Sprintf("%T", arg))
argumentString += "nil"
case reflect.Ptr:
p := v.Elem()
ret := make([]interface{}, p.Len())
for i := 0; i < p.Len(); i++ {
ret[i] = p.Index(i).Interface()
}
GenerateQueryCacheKey(ret...)
default:
log.Printf("Unhandled reflect type supplied! " + fmt.Sprintf("%T %T", arg, v))
argumentString += "nil"
}
}
h := md5.New()
io.WriteString(h, argumentString)
return fmt.Sprintf("%x", h.Sum(nil))
}
pg.Array 定义:https://sourcegraph.com/github.com/lib/pq/-/blob/array.go#L29:6
编辑:发布的 link 对 pg.Array 的定义不正确。不小心从sourcegraph.com.
抓错了库
通过从反射中恢复并使用更直接的方法解决。
我只是从 pg
导入了 types.Array 并创建了一个 interface{} 切片,然后手动将字符串添加到 interface{} 切片中,并使用扩展运算符为暂且。不确定这是否是最好的方法,但目前对我有用。
func GenerateQueryCacheKey(args ...interface{}) string {
var argumentString = ""
for _, arg := range args {
switch v := arg.(type) {
case bool:
argumentString += strconv.FormatBool(v)
case string:
argumentString += v
case int:
argumentString += strconv.Itoa(v)
case uint64:
argumentString += string(v)
case float64:
argumentString += strconv.FormatFloat(v, 'E', -1, 32)
case *types.Array:
stringArrayArgs := make([]interface{}, len(v.Value().([]string)))
for i, vs := range v.Value().([]string) {
stringArrayArgs[i] = vs
}
argumentString += GenerateQueryCacheKey(stringArrayArgs...)
case nil:
default:
log.Printf("%T was requested and not handled!\n", v)
argumentString += "nil"
}
}
h := md5.New()
io.WriteString(h, argumentString)
return fmt.Sprintf("%x", h.Sum(nil))
}
我正在使用 go-pg 编写自定义查询缓存系统,该系统采用传递给查询函数的查询参数并生成用于 Redis 的哈希键。我正在使用 Go 的反射来检查有效的参数类型,直到我使用 pg.Array 作为传递的参数。
Reflect 给了我 reflect.Ptr,但是我如何在调用 switch case 块时提取指针的 struct/Array?
func GenerateQueryCacheKey(args ...interface{}) string {
var argumentString = ""
for _, arg := range args {
v := reflect.ValueOf(arg)
switch v.Kind() {
case reflect.Array, reflect.Slice:
ret := make([]interface{}, v.Len())
for i := 0; i < v.Len(); i++ {
ret[i] = v.Index(i).Interface()
}
GenerateQueryCacheKey(ret...)
case reflect.Bool:
argumentString += strconv.FormatBool(v.Bool())
case reflect.String:
argumentString += v.String()
case reflect.Int:
argumentString += string(v.Int())
case reflect.Uint:
argumentString += string(v.Uint())
case reflect.Float32:
argumentString += strconv.FormatFloat(v.Float(), 'E', -1, 32)
case reflect.Invalid:
log.Printf("Invalid type handle! " + fmt.Sprintf("%T", arg))
argumentString += "nil"
case reflect.Ptr:
p := v.Elem()
ret := make([]interface{}, p.Len())
for i := 0; i < p.Len(); i++ {
ret[i] = p.Index(i).Interface()
}
GenerateQueryCacheKey(ret...)
default:
log.Printf("Unhandled reflect type supplied! " + fmt.Sprintf("%T %T", arg, v))
argumentString += "nil"
}
}
h := md5.New()
io.WriteString(h, argumentString)
return fmt.Sprintf("%x", h.Sum(nil))
}
pg.Array 定义:https://sourcegraph.com/github.com/lib/pq/-/blob/array.go#L29:6
编辑:发布的 link 对 pg.Array 的定义不正确。不小心从sourcegraph.com.
抓错了库通过从反射中恢复并使用更直接的方法解决。
我只是从 pg
导入了 types.Array 并创建了一个 interface{} 切片,然后手动将字符串添加到 interface{} 切片中,并使用扩展运算符为暂且。不确定这是否是最好的方法,但目前对我有用。
func GenerateQueryCacheKey(args ...interface{}) string {
var argumentString = ""
for _, arg := range args {
switch v := arg.(type) {
case bool:
argumentString += strconv.FormatBool(v)
case string:
argumentString += v
case int:
argumentString += strconv.Itoa(v)
case uint64:
argumentString += string(v)
case float64:
argumentString += strconv.FormatFloat(v, 'E', -1, 32)
case *types.Array:
stringArrayArgs := make([]interface{}, len(v.Value().([]string)))
for i, vs := range v.Value().([]string) {
stringArrayArgs[i] = vs
}
argumentString += GenerateQueryCacheKey(stringArrayArgs...)
case nil:
default:
log.Printf("%T was requested and not handled!\n", v)
argumentString += "nil"
}
}
h := md5.New()
io.WriteString(h, argumentString)
return fmt.Sprintf("%x", h.Sum(nil))
}