How to get the reflect.Type of an interface?

匿名 (未验证) 提交于 2019-12-03 02:06:01

问题:

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

回答1:

Do it like this:

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

Or in one line:

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


回答2:

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


回答3:

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



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!