go : How to get the reflect.Type of an interface?

https://stackoverflow.com/questions/7132848/how-to-get-the-reflect-type-of-an-interface#

 

How to get the reflect.Type of an interface?

Ask Question

up vote 11 down vote favorite

4

In order to determine whether a given type implements an interface using the reflect package, you need to pass a reflect.Type to reflect.Type.Implements(). How do you get one of those types?

As an example, trying to get the type of an uninitialized os.Error (interface) type does not work (it panics when you to call Kind() on it)

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

go

shareimprove this question

asked Aug 20 '11 at 15:49

laslowh

6,23622741

add a comment

3 Answers

active oldest votes

up vote 23 down vote accepted

Do it like this:

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

Or in one line:

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

shareimprove this answer

answered Aug 22 '11 at 20:33

Evan Shaw

16.3k35155

add a comment

up vote 3 down vote

Even Shaws response is correct, but brief. Some more details from the reflect.TypeOf method documentation:

// 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))

shareimprove this answer

answered Jan 9 '16 at 20:48

Kristoffer

314

add a comment

up vote 2 down vote

For googlers out there I just ran into the dreaded scannable dest type interface {} with >1 columns (XX) in result error.

Evan Shaw's answer did not work for me. Here is how I solved it. I am also using the lann/squirrel library, but you could easily take that out.

The solution really isn't that complicated, just knowing the magic combination of reflect calls to make.

The me.GetSqlx() function just returns an instance to *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...)
    }

Then to invoke it you can do:

    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
    }

This allows you to have strong types all over but have all the common logic in one place (CommonRepo in this example).

shareimprove this answer

answered Jun 17 '15 at 21:29

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值