douqianzha6213 2018-11-05 12:08
浏览 77
已采纳

Reflection.Pointer()返回的值不是值地址

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() works well, but I want to know why val.Pointer() return a value of **TableMeta? Why not a *TableMeta?The document of reflect says,

Pointer returns v's value as a uintptr. It returns uintptr instead of unsafe.Pointer so that code using reflect cannot obtain unsafe.Pointers without importing the unsafe package explicitly. It panics if v's Kind is not Chan, Func, Map, Ptr, Slice, or UnsafePointer.

In my mind:

info := &BookInfo{}
val := reflect.ValueOf(info)
ptr := val.Pointer()
meta := (*TableMeta)(unsafe.Pointer(val.Pointer()))

should work, but infact when I called val.Pointer(), the returned value is the pointer of *TableMeta(**TableMeta).

  • 写回答

1条回答 默认 最新

  • doudanglang5826 2018-11-05 12:37
    关注

    The value you have is a pointer to a BookInfo struct, it is of type *BookInfo. And the type of BookInfo.Meta field is also a pointer, it is of type *TableMeta, thus a *BookInfo can then be looked at as **TableMeta, hence the "double" pointer.

    It's true that the struct pointer points to its first field, but don't build on it. It's fragile. If you add a field before it, it'll break badly (which will only happen at runtime, no compile time messages due to package unsafe).

    So if the value is of type *BookInfo, simply obtain that out of the reflect.Value wrapper, then you can refer to its field like value.Meta, which will be of type *TableMeta. Avoid using package unsafe, especially if it's not needed.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 vs2022无法联网
  • ¥15 TCP的客户端和服务器的互联
  • ¥15 VB.NET操作免驱摄像头
  • ¥15 笔记本上移动热点开关状态查询
  • ¥85 类鸟群Boids——仿真鸟群避障的相关问题
  • ¥15 CFEDEM自带算例错误,如何解决?
  • ¥15 有没有会使用flac3d软件的家人
  • ¥20 360摄像头无法解绑使用,请教解绑当前账号绑定问题,
  • ¥15 docker实践项目
  • ¥15 利用pthon计算薄膜结构的光导纳