Mar*_*rco 0 reflection struct pointers go assertion
我想检查给定的f interface{}
函数参数是否是指向结构的指针,但不知何故陷入困境:
更新的片段:
package main
import (
"fmt"
"log"
"reflect"
)
func main() {
// Switch f between being a pointer or not
f := &struct{Foo string}{"Bar"}
if err := something(f); err != nil {
log.Fatal(err.Error())
}
}
func something(f interface{}) error {
if reflect.ValueOf(f).Kind() != reflect.Struct {
return fmt.Errorf("not struct; is %s", reflect.ValueOf(f).Kind().String())
}
if reflect.ValueOf(f).Kind() != reflect.Ptr {
return fmt.Errorf("not ptr; is %s", reflect.ValueOf(f).Kind().String())
}
// Deal with element values...
t := reflect.ValueOf(f).Elem()
for i := 0; i < t.NumField(); i++ {
fmt.Println(t.Type().String(), t.Field(i).Interface())
}
return nil
}
Run Code Online (Sandbox Code Playgroud)
如果f
作为指针传递给函数,我会得到一个not struct; is ptr
.
如果f
作为结构传递给函数,我会得到一个not ptr; is struct
.
有什么方法可以确保接口是指向结构的指针吗?似乎只要f
是一个指针,任何通过反射的进一步检查在这里就无法使用。我发现许多其他解决方案可以通过类型断言来处理,但我只是不知道这里会发生什么。基本上它可以是任何东西。
当然,我可以只使用指针检查,而将其他所有内容保留为“开发人员错误”。我只是想我能以某种方式处理它。
有任何想法吗?
小智 6
使用以下代码。检查指针,取消引用指针并检查结构。
func something(f interface{}) error {
v := reflect.ValueOf(f)
if v.Kind() != reflect.Ptr {
return fmt.Errorf("not ptr; is %T", f)
}
v := v.Elem() // dereference the pointer
if v.Kind() != reflect.Struct {
return fmt.Errorf("not struct; is %T", f)
}
t := v.Type()
for i := 0; i < t.NumField(); i++ {
sf := t.Field(i)
fmt.Println(sf.Name, v.Field(i).Interface())
}
return nil
}
Run Code Online (Sandbox Code Playgroud)