Golang Go语言中如何获取 value 为非导出结构体指针的 interface 的真实值

调试需要,要获得某个包中非导出结构体的值,大概是这样:

package third

type entry struct{ Value atomic.Value }

这个 Value 中储存的是另一个非导出结构体的指针 *third.anotherEntry

package third

type anotherEntry struct{ Key ExportStruct //某个导出的结构体 }

楼主用强制转换大法,搞到了 Value 的值,但问题是 Value.Load()是个 interface ,不能通过类型断言转换成*third.anotherEntry,尝试用反射:

reflect.ValueOf(Value.Load()).Elem().Field(0).Interface()

但反射也无法获得非导出结构体的 interface ,会直接 panic 。有什么黑科技可以用吗?


Golang Go语言中如何获取 value 为非导出结构体指针的 interface 的真实值

更多关于Golang Go语言中如何获取 value 为非导出结构体指针的 interface 的真实值的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

使用 unsafe 转换,定义一个结构一样的结构体
p := (*MyStruct)(unsafe.Pointer(entry))

更多关于Golang Go语言中如何获取 value 为非导出结构体指针的 interface 的真实值的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


atomic.Value 内部是一个 v any 所以直接通过 v 获取也是可以的(当然调 load 应该也可以)
可以试试如下
假设 e := &entry{}
v := reflect.ValueOf(e).Elem().FieldByName(“Value”)
s1 := reflect.NewAt(v.Type(), unsafe.Pointer(v.UnsafeAddr())).Elem()
result := reflect.Indirect(s1.FieldByName(“v”).Elem()).FieldByName(“Key”) // 因为你说的是指针所以要用 Indirect 转换一下
不出意外的话就能拿到 ExportStruct 了

在Golang中,如果你有一个interface{}类型的变量,并且它指向一个非导出(即未以大写字母开头命名的)结构体字段的指针,直接获取其真实值会面临一些挑战,因为非导出字段在包外部是不可见的。不过,你仍然可以通过类型断言和类型反射来获取其底层类型信息,但无法直接访问非导出字段。

假设你有一个接口变量i,并且你知道它实际上是指向某个具体结构体的指针,你可以这样进行类型断言:

var i interface{} = &someStruct{privateField: "value"}

// 假设你知道i是指向someStruct的指针
if s, ok := i.(*someStruct); ok {
    // 在这里,你可以访问someStruct中所有导出的字段和方法
    // 但无法直接访问privateField,因为它是非导出的
    fmt.Println(s.ExportedField) // 假设ExportedField是导出的
} else {
    fmt.Println("类型断言失败")
}

如果你需要更通用的解决方案,可以使用反射(reflect包):

v := reflect.ValueOf(i)
if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct {
    structType := v.Elem().Type()
    // 遍历结构体的字段,但无法访问非导出字段
    for i := 0; i < structType.NumField(); i++ {
        field := structType.Field(i)
        if field.PkgPath == "" { // 导出的字段
            fmt.Println(field.Name, field.Type)
        }
    }
}

注意,反射也无法直接访问非导出字段。

回到顶部