如何获取接口的reflect.Type?

问题描述 投票:0回答:4

为了确定给定类型是否使用reflect包实现了接口,您需要将reflect.Type传递给reflect.Type.Implements()。 如何获得其中一种类型?

举个例子,尝试获取未初始化的

error
(接口)类型确实不起作用(当你对其调用 Kind() 时它会出现恐慌)

var err error fmt.Printf("%#v\n", reflect.TypeOf(err).Kind())
    
go
4个回答
57
投票
这样做:

var err error t := reflect.TypeOf(&err).Elem()
或者一行:

t := reflect.TypeOf((*error)(nil)).Elem()
    

14
投票
即使Shaw的回应也是正确的,但很简短。 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)).Elem() fmt.Println(fileType.Implements(writerType))
    

0
投票
从 Go 1.22 开始,我们可以使用

reflect.TypeFor

 函数来获取 
reflect.Type
 值:

func main() { errorType := reflect.TypeFor[error]() err := errors.New("foo") println(reflect.TypeOf(err).Implements(errorType)) }
    

-1
投票
对于谷歌用户来说,我刚刚遇到了可怕的

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

)。

© www.soinside.com 2019 - 2024. All rights reserved.