将结构转换为字节片的特定地址

为了解析一个大文件而不必为每个结构复制字节,我想将结构直接转换为字节片中的地址。这仅仅是出于性能原因。我知道我可以使用 binary.Read() 从字节切片创建结构,但据我了解,这会复制字节,这是一件代价高昂的事情;因此我想避免在这个用例中使用这种方法。


我似乎确实已经转换了该结构,因为我确实在结构中获取了我期望的数据。但是,当我更改结构中的值时,它们不会更改结构地址应指向的字节片?对我来说重要的是文件(字节切片)反映了我的结构中数据的变化。


如何让结构体在文件中的相应地址上工作?


这是我到目前为止所做的演示:


type T struct {

    A uint8

}


func main() {


    data := []byte{0xA, 0xB, 0xC}


    // Cast bytes to struct

    pointer := *(*uint8)(unsafe.Pointer(&data[0]))

    fmt.Printf("ptr:\t0x%x\n", pointer)


    t2 := *(*T)(unsafe.Pointer(&pointer))

    fmt.Printf("T:\t0x%x\n\n", t2.A)

    // byte casting to struct ends here


    // test

    t2.A = 0x0 // I expect this to change for data as well but it does not.


    fmt.Println("AFTER CHANGE OF t2.A")

    fmt.Printf("data[0]:0x%x\n", data[0])

    fmt.Printf("ptr:\t0x%x\n\n", pointer)


    fmt.Println("WHY ARE THESE ON DIFFERENT ADDRESSES?")

    fmt.Printf("DataAddr: 0x%p\n", data)

    fmt.Printf("PtrAddr: 0x%p\n", &pointer)

    fmt.Printf("T2Addr: 0x%p\n", &t2)


}

这打印出:


ptr:    0xa

T:      0xa


AFTER CHANGE OF t2.A - the original data slice has not been altered.

data[0]:0xa

ptr:    0xa


ADDRESSES

DataAddr: 0x0xc000094010

PtrAddr: 0x0xc000094013

T2Addr: 0x0xc000094030


小唯快跑啊
浏览 103回答 1
1回答

POPMUISE

您正确地转换了指针,但随后取消引用它,这会生成一个副本。然后,您继续获取副本的地址,转换该指针,然后再次取消引用它(这会生成另一个副本)。修改任何副本不会对其他副本产生任何影响。因此,不要取消引用指针(最终我们只是修改位于同一内存位置的指向值):data := []byte{0xA, 0xB, 0xC}// Cast bytes to structpointer := (*uint8)(unsafe.Pointer(&data[0]))fmt.Printf("ptr:\t0x%x\n", *pointer)t2 := (*T)(unsafe.Pointer(pointer))fmt.Printf("T:\t0x%x\n\n", t2.A)// byte casting to struct ends here// testt2.A = 0x0 // This will also change datafmt.Println("AFTER CHANGE OF t2.A")fmt.Printf("data[0]:0x%x\n", data[0])fmt.Printf("ptr:\t0x%x\n\n", *pointer)fmt.Println("ADDRESSES ARE ALL THE SAME:")fmt.Printf("DataAddr: 0x%p\n", &data[0])fmt.Printf("PtrAddr: 0x%p\n", pointer)fmt.Printf("T2Addr: 0x%p\n", t2)输出(在Go Playground上尝试):ptr:    0xaT:  0xaAFTER CHANGE OF t2.Adata[0]:0x0ptr:    0x0ADDRESSES ARE ALL THE SAME:DataAddr: 0x0x40e020PtrAddr: 0x0x40e020T2Addr: 0x0x40e020
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go