ホームページ >バックエンド開発 >Golang >golang バイトを構造体に変換

golang バイトを構造体に変換

PHPz
PHPzオリジナル
2023-05-15 09:07:361429ブラウズ

Golang でのバイト配列から構造体への変換は一般的な問題であり、多くの開発者がこの問題に遭遇するでしょう。 Golang のバイト配列はバイナリ データの処理には非常に便利ですが、構造体などの複雑なデータ構造の場合は手動で処理する必要があり、コードが長くなりエラーが発生しやすくなります。この記事では、Golang を使用してバイト配列を構造体に変換する方法を紹介します。

1. 安全でない変換を通じて

安全でないパッケージ内の Pointer を使用して、バイト配列と構造体の間で変換できます。サンプル コードは次のとおりです。

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)
}

上記のコードでは、Person 構造体を作成し、それをバイト配列に変換し、ポインタを介して Person 構造体に再変換します。 unsafe パッケージの Pointer と uintptr を使用して、ポインターと整数の間で変換します。

このコードを実行すると、出力結果は次のようになります。

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

このメソッドは変換を実現できますが、セキュリティ上のリスクがあり、使用には注意が必要です。

2.reflect による変換

Reflect パッケージは Golang の非常に強力なパッケージで、これを使用して変数の型推論を実行し、関数を呼び出すことができます。バイト配列と構造体の間で変換する場合、reflect パッケージの Value と Type を使用できます。サンプル コードは次のとおりです。

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)
}

reflect パッケージの Type と Value を使用して構造体のサイズと値を取得し、reflect.ValueOf(&p).Elem() を通じてメモリ内の構造体を取得します。 .UnsafeAddr() ポインタを使用し、型変換に uintptr と unsafe.Pointer を使用し、最後に代入のためにバイト配列を走査すると、バイト配列を構造体に変換できます。

このコードを実行すると、出力結果は次のようになります。

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

バイト配列と構造体の格納順序が異なるため、バイト配列の順序を正しく処理する必要があります。構造体に変換します。

概要

Golang でバイト配列と構造体を変換するには 2 つの方法があります: 1 つは、unsafe パッケージを使用してポインタ、整数、およびバイト配列の間で変換する方法、型、値、およびバイト配列間の変換アドレスは、reflect パッケージを通じて実行されます。どちらの方法にもそれぞれ長所と短所があり、使用する場合は状況に応じて選択する必要があります。同時に、バイト配列と構造体を変換するときは、バイト配列の順序や構造体のフィールドの型などの詳細に注意する必要があります。

以上がgolang バイトを構造体に変換の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。