我正在使用第三方软件包,该软件包允许您通过导出的函数创建某些非导出类型的结构。
package squirrel
type expr struct {
sql string
args []interface{}
}
func Expr(sql string, args ...interface{}) expr {
return expr{sql: sql, args: args}
}
由于该库的其他功能接收数据的方式,我最终得到了这样的一张图:
m := map[string]interface{} {
"col1": 123,
"col2": "a_string",
"col3": Expr("now()"),
}
但是由于该库中的功能不同,我需要从该地图中过滤掉所有squirrel.expr
。
很明显,这样做无法直接声明类型:
filtered := make(map[string]interface{})
for k, v := range m {
switch v.(type) {
case squirrel.expr:
continue
default:
filtered[k] = v
}
}
还有另一种方法可以达到相同的结果吗?
答案 0 :(得分:5)
您可以使用反射将值的类型与squirrel.expr
的类型进行比较。这里的类型表示reflect.Type
获取的reflect.TypeOf()
描述符。
例如:
m := map[string]interface{}{
"col1": 123,
"col2": "a_string",
"col3": squirrel.Expr("now()"),
}
fmt.Println(m)
exprType := reflect.TypeOf(squirrel.Expr(""))
filtered := make(map[string]interface{})
for k, v := range m {
if reflect.TypeOf(v) == exprType {
continue
}
filtered[k] = v
}
fmt.Println(filtered)
这将输出:
map[col1:123 col2:a_string col3:{now() []}]
map[col1:123 col2:a_string]
注意:
我们通过传递reflect.Type
调用的返回值(类型为squirrel.Expr()
)来获取要过滤掉的值的squirrel.expr
描述符。在这种情况下这很好,但是如果仅为了获取类型而调用此函数是不可行的(例如,该调用具有必须避免的副作用),我们可以避免这种情况。我们可以使用反射来获取reflect.Type
函数本身的squirrel.Expr
描述符,并获取其返回类型的类型描述符。这是可以做到的:
exprType := reflect.TypeOf(squirrel.Expr).Out(0)