我有一个函数,可以遍历作为参数传递的接口的所有字段。为了实现这一点,我正在使用反射。问题是我不知道如何获取非指针字段的地址。这是一个例子:
type Z struct {
Id int
}
type V struct {
Id int
F Z
}
type T struct {
Id int
F V
}
上面的代码代表了我的测试结构。现在,这是遍历指定结构并列出有关其详细信息的实际函数:
func InspectStruct(o interface{}) {
val := reflect.ValueOf(o)
if val.Kind() == reflect.Interface && !val.IsNil() {
elm := val.Elem()
if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr {
val = elm
}
}
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
for i := 0; i < val.NumField(); i++ {
valueField := val.Field(i)
typeField := val.Type().Field(i)
address := "not-addressable"
if valueField.Kind() == reflect.Interface && !valueField.IsNil() {
elm := valueField.Elem()
if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr {
valueField = elm
}
}
if valueField.Kind() == reflect.Ptr {
valueField = valueField.Elem()
}
if valueField.CanAddr() {
address = fmt.Sprint(valueField.Addr().Pointer())
}
fmt.Printf("Field Name: %s,\t Field Value: %v,\t Address: %v\t, Field type: %v\t, Field kind: %v\n", typeField.Name,
valueField.Interface(), address, typeField.Type, valueField.Kind())
if valueField.Kind() == reflect.Struct {
InspectStruct(valueField.Interface())
}
}
}
这是结构实例化/初始化之后的实际测试:
t := new(T)
t.Id = 1
t.F = *new(V)
t.F.Id = 2
t.F.F = *new(Z)
t.F.F.Id = 3
InspectStruct(t)
最后是InspectStruct调用的输出:
Field Name: Id, Field Value: 1, Address: 408125440 , Field type: int , Field kind: int
Field Name: F, Field Value: {2 {3}}, Address: 408125444 , Field type: main.V , Field kind: struct
Field Name: Id, Field Value: 2, Address: not-addressable , Field type: int , Field kind: int
Field Name: F, Field Value: {3}, Address: not-addressable , Field type: main.Z , Field kind: struct
Field Name: Id, Field Value: 3, Address: not-addressable , Field type: int , Field kind: int
如您所见,我正在使用递归,因此,如果其中一个字段是结构类型,则可以为其调用InspectStruct。 我的问题是,尽管所有字段都已针对整个结构“
t”的层次结构进行了初始化,但我无法获得比“ t”高的深度的任何字段的地址。 我真的很感谢您的帮助。
通过reflect.Value
而不是interface{}
似乎可以解决问题,但是我不知道为什么valueField.Interface()
不起作用。
工作示例:http :
//play.golang.org/p/nleA2YWMj8
func InspectStructV(val reflect.Value) {
if val.Kind() == reflect.Interface && !val.IsNil() {
elm := val.Elem()
if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr {
val = elm
}
}
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
for i := 0; i < val.NumField(); i++ {
valueField := val.Field(i)
typeField := val.Type().Field(i)
address := "not-addressable"
if valueField.Kind() == reflect.Interface && !valueField.IsNil() {
elm := valueField.Elem()
if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr {
valueField = elm
}
}
if valueField.Kind() == reflect.Ptr {
valueField = valueField.Elem()
}
if valueField.CanAddr() {
address = fmt.Sprintf("0x%X", valueField.Addr().Pointer())
}
fmt.Printf("Field Name: %s,\t Field Value: %v,\t Address: %v\t, Field type: %v\t, Field kind: %v\n", typeField.Name,
valueField.Interface(), address, typeField.Type, valueField.Kind())
if valueField.Kind() == reflect.Struct {
InspectStructV(valueField)
}
}
}
func InspectStruct(v interface{}) {
InspectStructV(reflect.ValueOf(v))
}
Go语言程序中对指针获取反射对象时,可以通过 reflect.Elem() 方法获取这个指针指向的元素类型。这个获取过程被称为取元素,等效于对指针类型变量做了一个 操作,代码如下: 代码输出如下: name: '' kind: 'ptr' element name: 'cat', element kind: 'struct' 代码说明如下: 第 15 行,创建了cat结构体的实例,ins 是一个
假设有一个结构 我得到一个指向该结构的成员的指针,比如作为某个函数的参数: 如何获取指向包含对象的指针?最重要的是:在不违反标准中的某些规则的情况下,也就是说,我想要标准定义的行为,而不是未定义或实现定义的行为。 附带说明:我知道这规避了类型安全。
问题内容: 我无法获取字段值。我想做的是在运行时获取对象。请让我知道我要去哪里了。 测试类 } EX.class } 问题答案: 像这样 或者,您可以使用类的方法在运行时获取对象的实例。您仍然需要首先设置该实例变量,否则它将没有任何值。 例如 或者,在其构造函数中有两个参数的地方,例如String和int … 或者您可以在运行时使用它为其构造函数查询 注意:我特意省略了将在此创建的对象强制转换为预
问题内容: 我想知道是否有可能为python列表中的元素获取“指针”。这样,我将能够直接访问我的元素而无需知道我元素的索引。我的意思是,您可以在列表中的任何位置添加元素。在开始,中间甚至结束时,各个元素都不会从其实际存储位置移出。从理论上讲,应该可以执行以下操作: [1] 元素将在此处充当指针。 [0,1,2] 此时,即使列表中的索引已更改,我仍然可以直接访问该元素。 我要这样做的原因是,在我的程
我尝试使用dropWizard库获取JVM度量值(MemoryUsageGaugeSet、GarbageCollectionUsageGaigeSet) 代码实现。 我得到的结果是 {heap.committed=com.codahale.metrics.jvm.MemoryUsageGaugeSet$8@d16011, non-heap.used=com.codahale.metrics.jvm
我正在创建许多POJO,并且必须为每个POJO创建方法。我认为创建一个类来使用反射API为我完成工作会更容易——在一个地方创建功能并在每个POJO中使用它。 POJO中的所有字段都是私有的。POJO是JSON对象的Java对象表示。 要求是遍历类中的字段,并列出字段和值。 我目前正在一个名为的类上测试该功能。 下面是我用来列出字段名和值的类: 我将< code>ChannelResource类的一