Как получить отражение. Тип интерфейса?

Чтобы определить, реализует ли данный тип интерфейса интерфейс с использованием пакета отражения, вам необходимо передать рефлексию. Тип для отражения. Type.Implements(). Как вы получаете один из этих типов?

В качестве примера, попытка получить тип неинициализированного типа os.Error(interface) работает не (он паникует, когда вы вызываете на нем Kind())

var err os.Error
fmt.Printf("%#v\n", reflect.TypeOf(err).Kind())

Ответ 1

Сделайте это так:

var err *os.Error
t := reflect.TypeOf(err).Elem()

Или в одной строке:

t := reflect.TypeOf((*os.Error)(nil)).Elem()

Ответ 2

Даже реакция Shaws правильная, но краткая. Еще несколько деталей из документации метода reflect.TypeOf:

// As interface types are only used for static typing, a
// common idiom to find the reflection Type for an interface
// type Foo is to use a *Foo value.

writerType := reflect.TypeOf((*io.Writer)(nil)).Elem()

fileType := reflect.TypeOf((*os.File)(nil))
fmt.Println(fileType.Implements(writerType))

Ответ 3

Для гуглеров я просто столкнулся с ужасной ошибкой scannable dest type interface {} with >1 columns (XX) in result.

Ответ Эвана Шоу не помог мне. Вот как я это решил. Я также использую библиотеку lann/squirrel, но вы можете легко принять это.

Решение действительно не так сложно, просто зная магическую комбинацию отражать звонки, чтобы сделать.

Функция me.GetSqlx() просто возвращает экземпляр в *sqlx.DB

    func (me *CommonRepo) Get(query sq.SelectBuilder, dest interface{}) error {
      sqlst, args, err := query.ToSql()
      if err != nil {
        return err
      }
      // Do some reflection magic so that Sqlx doesn't hork on interface{}
      v := reflect.ValueOf(dest)
      return me.GetSqlx().Get(v.Interface(), sqlst, args...)
    }
    func (me *CommonRepo) Select(query sq.SelectBuilder, dest interface{}) error {
      sqlst, args, err := query.ToSql()
      if err != nil {
        return err
      }
      // Do some reflection magic so that Sqlx doesn't hork on interface{}
      v := reflect.ValueOf(dest)
      return me.GetSqlx().Select(v.Interface(), sqlst, args...)
    }

Затем, чтобы вызвать его, вы можете:

    func (me *myCustomerRepo) Get(query sq.SelectBuilder) (rec Customer, err error) {
      err = me.CommonRepo.Get(query, &rec)
      return
    }
    func (me *myCustomerRepo) Select(query sq.SelectBuilder) (recs []Customer, err error) {
      err = me.CommonRepo.Select(query, &recs)
      return
    }

Это позволяет вам иметь сильные типы на всем протяжении, но имеет общую логику в одном месте (CommonRepo в этом примере).