如何获取界面的reflect.Type?

时间:2011-08-20 15:49:30

标签: go

为了确定给定类型是否使用reflect包实现接口,您需要将reflect.Type传递给reflect.Type.Implements()。你怎么得到这些类型之一?

例如,尝试获取未初始化的os.Error(接口)类型的类型工作(当你在它上面调用Kind()时会发生恐慌)

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

3 个答案:

答案 0 :(得分:26)

这样做:

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

或者在一行中:

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

答案 1 :(得分:6)

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

答案 2 :(得分:2)

对于那里的googlers,我只是遇到了可怕的scannable dest type interface {} with >1 columns (XX) in result错误。

Evan Shaw的回答对我不起作用。这是我如何解决它。我也在使用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)。