I am using a 3rd party package, which allows you to create structures of a certain non-exported type through an exported function.
package squirrel
type expr struct {
sql string
args []interface{}
}
func Expr(sql string, args ...interface{}) expr {
return expr{sql: sql, args: args}
}
Because of the way some other function of this library accepts data, I ended up with such a map:
m := map[string]interface{} {
"col1": 123,
"col2": "a_string",
"col3": Expr("now()"),
}
but because of a different function in this library I need to filter out all squirrel.expr
from this map.
Obviously, I wasn't able to assert the type directly, by doing so:
filtered := make(map[string]interface{})
for k, v := range m {
switch v.(type) {
case squirrel.expr:
continue
default:
filtered[k] = v
}
}
Is there another way to achieve the same result?
You may use reflection to compare the type of values to the type of squirrel.expr
. Type here means the reflect.Type
descriptors, acquired by reflect.TypeOf()
.
For example:
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)
This will output:
map[col1:123 col2:a_string col3:{now() []}]
map[col1:123 col2:a_string]
Note:
We obtained the reflect.Type
descriptor of the values we want to filter out by passing the return value of a squirrel.Expr()
call (which is of type squirrel.expr
). This is fine in this case, but if it is unfeasible to call this function just to get the type (e.g. the call has side effects which must be avoided), we can avoid that. We can use reflection to obtain the reflect.Type
descriptor of the squirrel.Expr
function itself, and get the type descriptor of its return type. This is how it could be done:
exprType := reflect.TypeOf(squirrel.Expr).Out(0)