golang byte转struct

PHPz
Lepaskan: 2023-05-15 09:07:36
asal
1334 orang telah melayarinya

Menukar tatasusunan bait kepada struct dalam Golang ialah masalah biasa yang akan dihadapi oleh ramai pembangun. Tatasusunan bait Golang sangat mudah untuk memproses data binari, tetapi untuk struktur data yang kompleks, seperti struct, pemprosesan manual diperlukan kod sedemikian panjang dan mudah ralat. Artikel ini akan memperkenalkan cara menukar tatasusunan bait kepada struct melalui Golang.

1. Penukaran melalui tidak selamat

Kita boleh menggunakan Penunjuk dalam pakej tidak selamat untuk menukar antara tatasusunan bait dan struct. Kod sampel adalah seperti berikut:

package main

import (
    "fmt"
    "reflect"
    "unsafe"
)

type Person struct {
    Name string
    Age  int
}

func main() {
    p := Person{Name: "Tom", Age: 18}

    size := int(unsafe.Sizeof(p))
    fmt.Printf("struct size: %d
", size)

    b := make([]byte, size)
    pptr := unsafe.Pointer(&p)

    for i := 0; i < size; i++ {
        b[i] = *(*byte)(unsafe.Pointer(uintptr(pptr) + uintptr(i)))
    }

    fmt.Printf("byte array: %v
", b)

    q := (*Person)(unsafe.Pointer(&b[0]))
    fmt.Printf("person: %v
", q)
}
Salin selepas log masuk

Dalam kod di atas, kami mencipta struktur Orang, menukarnya kepada tatasusunan bait dan menukarnya semula kepada struktur Orang melalui penuding. Kami menggunakan Penunjuk dan uintptr daripada pakej yang tidak selamat untuk menukar antara penunjuk dan integer.

Selepas menjalankan kod ini, hasil output adalah seperti berikut:

struct size: 16
byte array: [84 111 109 0 0 0 0 0 0 0 0 0 18 0 0 0]
person: &{Tom 18}
Salin selepas log masuk

Walaupun kaedah ini boleh mencapai penukaran, ia mempunyai risiko keselamatan tertentu dan perlu digunakan dengan berhati-hati.

2. Penukaran melalui reflect

Pakej Reflect ialah pakej yang sangat berkuasa di Golang Anda boleh menggunakannya untuk melakukan inferens jenis pada pembolehubah dan fungsi panggilan. Apabila menukar antara tatasusunan bait dan struct, kita boleh menggunakan Nilai dan Jenis daripada pakej mencerminkan. Kod sampel adalah seperti berikut:

package main

import (
    "fmt"
    "reflect"
)

type Person struct {
    Name string
    Age  int
}

func main() {
    p := Person{Name: "Tom", Age: 18}

    size := int(reflect.TypeOf(p).Size())
    fmt.Printf("struct size: %d
", size)

    b := make([]byte, size)
    reflect.ValueOf(&p).Elem().Interface()
    for i := 0; i < size; i++ {
        b[i] = *(*byte)(unsafe.Pointer(uintptr(reflect.ValueOf(&p).Elem().UnsafeAddr()) + uintptr(i)))
    }

    fmt.Printf("byte array: %v
", b)

    var q Person
    s := reflect.ValueOf(&q).Elem()
    for i := 0; i < size; i++ {
        s.Field(i).SetInt(int64(b[i]))
    }

    fmt.Printf("person: %v
", q)
}
Salin selepas log masuk

Kami menggunakan Jenis dan Nilai dalam pakej mencerminkan untuk mendapatkan saiz dan nilai struktur, dan mendapatkan struktur dalam ingatan melalui reflect.ValueOf(&p).Elem() Penunjuk .UnsafeAddr(), kemudian gunakan uintptr dan unsafe.Pointer untuk penukaran jenis, dan akhirnya melintasi tatasusunan bait untuk tugasan, kemudian tatasusunan bait boleh ditukar menjadi struct.

Selepas menjalankan kod ini, output adalah seperti berikut:

struct size: 16
byte array: [84 111 109 0 0 0 0 0 0 0 0 0 18 0 0 0]
person: {Tom 84}
Salin selepas log masuk

Disebabkan perbezaan dalam susunan storan antara tatasusunan bait dan struct, kami perlu mengendalikan susunan tatasusunan bait secara manual untuk betul menukar kepada struct.

Ringkasan

Terdapat dua cara untuk menukar tatasusunan bait dan struct dalam Golang: satu ialah menukar antara penuding, integer dan tatasusunan bait melalui pakej yang tidak selamat; alamat dilakukan melalui pakej mencerminkan. Kedua-dua kaedah mempunyai kelebihan dan kekurangan mereka sendiri, dan anda perlu memilih mengikut situasi tertentu apabila menggunakannya. Pada masa yang sama, apabila menukar tatasusunan dan struktur bait, anda perlu memberi perhatian kepada butiran seperti susunan tatasusunan bait dan jenis medan dalam struct.

Atas ialah kandungan terperinci golang byte转struct. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!