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