从指针接口获取结构的大小

我正在尝试从接口中一般获取任何结构的大小。这适用于按值传递的对象,但我不知道如何在使用接口传递引用时获取对象的大小。

这是一个说明我遇到的问题的示例: https://play.golang.org/p/QXXZm-j7_hZ

package main


import (

    "fmt"

    "reflect"

    "unsafe"

)


type T struct {

    c [50]byte

}


func main() {

    fmt.Println("Hello, playground")


    var t T

    s := unsafe.Sizeof(t)

    fmt.Println("expected size", s)

    getSize(t, &t)

}


func getSize(valueObject interface{}, referenceObject interface{}) {

    vs := []uintptr{

        unsafe.Sizeof(valueObject),

        unsafe.Sizeof(reflect.ValueOf(valueObject)),

        reflect.TypeOf(valueObject).Size(), // THIS WORKS FOR VALUE

        reflect.TypeOf(reflect.ValueOf(valueObject)).Size(),

        0, //reflect.TypeOf(reflect.ValueOf(valueObject).Elem()).Size(), //EXCEPTION ACCESSING ELEM WITH VALUE

        0, //reflect.TypeOf(reflect.ValueOf(valueObject).Elem()).Size(), //EXCEPTION ACCESSING ELEM WITH VALUE

        0, //unsafe.Sizeof(reflect.ValueOf(valueObject).Elem()), //EXCEPTION ACCESSING ELEM WITH VALUE

        0, //unsafe.Sizeof(reflect.TypeOf(reflect.ValueOf(valueObject).Elem())), //EXCEPTION ACCESSING ELEM WITH VALUE

    }

    fmt.Println("valueObject size", vs)


    rs := []uintptr{

        unsafe.Sizeof(referenceObject),

        unsafe.Sizeof(reflect.ValueOf(referenceObject)),

        reflect.TypeOf(referenceObject).Size(),

        reflect.TypeOf(reflect.ValueOf(referenceObject)).Size(),

        reflect.TypeOf(reflect.ValueOf(referenceObject).Elem()).Size(),

        reflect.TypeOf(reflect.ValueOf(referenceObject).Elem()).Size(),

        unsafe.Sizeof(reflect.ValueOf(referenceObject).Elem()),

        unsafe.Sizeof(reflect.TypeOf(reflect.ValueOf(referenceObject).Elem())),

    }


    fmt.Println("referenceObject size", rs)

}

这是输出:


expected size 50

valueObject size [8 12 50 12 0 0 0 0]

referenceObject size [8 12 4 12 12 12 12 8]

正如您所看到的,当我使用 传递值时,我可以获得对象的大小reflect.TypeOf(valueObject).Size(),但是当我传递引用时,没有任何东西给我正确的大小。


12345678_0001
浏览 108回答 1
1回答

翻阅古今

go 中没有“引用”类型,指针和其他任何东西一样都是一个值,你当然可以得到指针本身的大小。您还混淆了您想要的大小的reflect.Value、 theinterface{}和实际值。导致这种混淆的原因是包unsafe是特殊的,它不接受接口值,而是可以直接接受任何值,这由编译器正确处理。您可以通过单独的调用处理指针和结构,或者检查您是否有指针并调用Elem():// structreflect.ValueOf(i).Type().Size()// pointerreflect.ValueOf(i).Elem().Type().Size()但是,由于可选地取消引用指针是很常见的,您可以使用reflect.Indirect一次处理这两种类型:reflect.Indirect(reflect.ValueOf(i)).Type().Size()https://play.golang.org/p/og-uMDXCmEr作为参考,一些尝试实际采取的描述:// size of the interface valueunsafe.Sizeof(valueObject)// size of reflect.Valueunsafe.Sizeof(reflect.ValueOf(valueObject))// size of the reflect.Value type reflect.TypeOf(reflect.ValueOf(valueObject)).Size()// size of the interface valueunsafe.Sizeof(referenceObject)// size of the reflect.Valueunsafe.Sizeof(reflect.ValueOf(referenceObject))// size of the pointer valuereflect.TypeOf(referenceObject).Size()// size of the reflect.Value typereflect.TypeOf(reflect.ValueOf(referenceObject)).Size(),// size of the of reflect.Value type againreflect.TypeOf(reflect.ValueOf(referenceObject).Elem()).Size()// size of the reflect.Valueunsafe.Sizeof(reflect.ValueOf(referenceObject).Elem()),// size of the reflect.Type interface valueunsafe.Sizeof(reflect.TypeOf(reflect.ValueOf(referenceObject).Elem())),
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go