为了账号安全,请及时绑定邮箱和手机立即绑定

reflect.Pointer() 返回值不是值地址

reflect.Pointer() 返回值不是值地址

Go
蝴蝶刀刀 2023-05-08 14:31:19
type BookInfo struct {    Meta         *TableMeta    ...}func (si *schemaInfo) getTabInfo(obj interface{}) (*tabInfo, error) {    typ := reflect.TypeOf(obj)    val := reflect.ValueOf(obj)    if typ.Kind() != reflect.Ptr {        return nil, errors.New("nborm.schemaInfo.getDBInfo() error: required a pointer")    }    meta := *(**TableMeta)(unsafe.Pointer(val.Pointer()))    ... }getTabInfo()效果很好,但我想知道为什么val.Pointer()返回一个值**TableMeta?为什么不呢*TableMeta?文件reflect说,指针将 v 的值作为 uintptr 返回。它返回 uintptr 而不是 unsafe.Pointer,这样使用 reflect 的代码就无法在不显式导入 unsafe 包的情况下获得 unsafe.Pointers。如果 v 的 Kind 不是 Chan、Func、Map、Ptr、Slice 或 UnsafePointer,它会恐慌。在我脑海里:info := &BookInfo{}val := reflect.ValueOf(info)ptr := val.Pointer()meta := (*TableMeta)(unsafe.Pointer(val.Pointer()))应该可以,但实际上当我调用 时,返回值是( )val.Pointer()的指针。*TableMeta**TableMeta
查看完整描述

1 回答

?
ibeautiful

TA贡献1993条经验 获得超5个赞

您拥有的值是指向结构的指针BookInfo,它的类型为*BookInfo. 并且字段的类型BookInfo.Meta也是一个指针,它是类型*TableMeta,因此*BookInfo可以将 a 视为**TableMeta,因此是“双”指针。

结构指针确实指向它的第一个字段,但不要在其上构建。很脆弱。如果您在它之前添加一个字段,它会严重损坏(这只会在运行时发生,由于 package 而没有编译时消息unsafe)。

因此,如果该值是 type *BookInfo,只需从reflect.Value包装器中获取它,然后您就可以引用它的字段value.Meta,如 ,这将是 type *TableMeta。避免使用 package unsafe,尤其是在不需要的时候。


查看完整回答
反对 回复 2023-05-08
  • 1 回答
  • 0 关注
  • 143 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信