猿问

reflect.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()效果很好,但我想知道为什么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


蝴蝶刀刀
浏览 144回答 1
1回答

ibeautiful

您拥有的值是指向结构的指针BookInfo,它的类型为*BookInfo. 并且字段的类型BookInfo.Meta也是一个指针,它是类型*TableMeta,因此*BookInfo可以将 a 视为**TableMeta,因此是“双”指针。结构指针确实指向它的第一个字段,但不要在其上构建。很脆弱。如果您在它之前添加一个字段,它会严重损坏(这只会在运行时发生,由于 package 而没有编译时消息unsafe)。因此,如果该值是 type *BookInfo,只需从reflect.Value包装器中获取它,然后您就可以引用它的字段value.Meta,如 ,这将是 type *TableMeta。避免使用 package unsafe,尤其是在不需要的时候。
随时随地看视频慕课网APP

相关分类

Go
我要回答