Утверждение типа неэкспортированного типа - PullRequest
1 голос
/ 10 апреля 2019

Я использую сторонний пакет, который позволяет создавать структуры определенного неэкспортированного типа с помощью экспортируемой функции.

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
    }
}

Есть ли другой способ достичь того же результата?

1 Ответ

5 голосов
/ 10 апреля 2019

Вы можете использовать отражение, чтобы сравнить тип значений с типом 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...