Ich habe eine Instanz einer von mir definierten Struktur und möchte diese in ein Byte-Array konvertieren. Ich habe [] Byte (my_struct) ausprobiert, aber das hat nicht funktioniert. Ich wurde auch auf das binary package hingewiesen, bin mir aber nicht sicher, welche Funktion ich verwenden soll und wie ich es verwenden soll. Ein Beispiel wäre sehr dankbar.
Ich nehme an, Sie wollen so etwas wie C damit umgehen. Dafür gibt es keine eingebaute Möglichkeit. Sie müssen Ihre eigene Serialisierung und Deserialisierung für und von Bytes für Ihre Struktur definieren. Das Binärpaket hilft Ihnen beim Kodieren der Felder in Ihrer Struktur in Bytes, die Sie dem Bytearray hinzufügen können. Sie müssen jedoch die Längen und Offsets im Bytearray angeben, die die Felder Ihrer Struktur enthalten sollen.
Ihre anderen Optionen sind, eines der Kodierungspakete zu verwenden: http://golang.org/pkg/encoding/ wie gob oder json.
EDIT:
Da Sie dies für die Erstellung eines Hashs wünschen, wie Sie in Ihrem Kommentar sagen, ist es am einfachsten, []byte(fmt.Sprintf("%v", struct))
zu verwenden: http://play.golang.org/p/yY8mSdZ_kf
Eine mögliche Lösung ist das Standardpaket "encoding/gob"
. Das gob-Paket erstellt einen Encoder/Decoder, der jede Struktur in ein Byte-Array codieren und dieses Array dann wieder in eine Struktur decodieren kann. Es gibt einen großartigen Beitrag, hier .
Wie andere darauf hingewiesen haben, ist es notwendig, ein solches Paket zu verwenden, da die Struktur von Natur aus unbekannte Größen aufweist und nicht in Byte-Arrays umgewandelt werden kann.
Ich habe etwas Code und ein play eingefügt.
package main
import (
"bytes"
"encoding/gob"
"fmt"
"log"
)
type P struct {
X, Y, Z int
Name string
}
type Q struct {
X, Y *int32
Name string
}
func main() {
// Initialize the encoder and decoder. Normally enc and dec would be
// bound to network connections and the encoder and decoder would
// run in different processes.
var network bytes.Buffer // Stand-in for a network connection
enc := gob.NewEncoder(&network) // Will write to network.
dec := gob.NewDecoder(&network) // Will read from network.
// Encode (send) the value.
err := enc.Encode(P{3, 4, 5, "Pythagoras"})
if err != nil {
log.Fatal("encode error:", err)
}
// HERE ARE YOUR BYTES!!!!
fmt.Println(network.Bytes())
// Decode (receive) the value.
var q Q
err = dec.Decode(&q)
if err != nil {
log.Fatal("decode error:", err)
}
fmt.Printf("%q: {%d,%d}\n", q.Name, *q.X, *q.Y)
}
Sie sollten anstelle eines Strings einen Byte-Puffer verwenden. Die anderen vorgeschlagenen Methoden erstellen einen SHA1 mit variabler Länge. Die Standardlänge des SHA1 muss 20 Byte (160 Bit) betragen.
package main
import (
"crypto/sha1"
"fmt"
"encoding/binary"
"bytes"
)
type myStruct struct {
ID string
Data string
}
func main() {
var bin_buf bytes.Buffer
x := myStruct{"1", "Hello"}
binary.Write(&bin_buf, binary.BigEndian, x)
fmt.Printf("% x", sha1.Sum(bin_buf.Bytes()))
}
Probieren Sie es selbst aus: http://play.golang.org/p/8YuM6VIlLV
Es ist eine wirklich einfache Methode und funktioniert prima.
Ich weiß, dass dieser Thread alt ist, aber keine der Antworten wurde akzeptiert und es gibt einen ziemlich einfachen Weg, dies zu tun.
https://play.golang.org/p/TedsY455EBD
wichtiger Code vom Spielplatz
import (
"bytes"
"fmt"
"encoding/json"
)
type MyStruct struct {
Name string `json:"name"`
}
testStruct := MyStruct{"hello world"}
reqBodyBytes := new(bytes.Buffer)
json.NewEncoder(reqBodyBytes).Encode(testStruct)
reqBodyBytes.Bytes() // this is the []byte
Haben Sie darüber nachgedacht, es zu bson zu serialisieren? http://labix.org/gobson
Werfen Sie einen Blick auf https://blog.golang.org/go-slices-usage-and-internals Schneiden Sie speziell die internen Elemente. Die Idee ist, die interne Struktur von Slice zu imitieren und auf unsere Struktur statt auf eine Bytefolge zu verweisen:
package main
import (
"fmt"
"unsafe"
)
// our structure
type A struct {
Src int32
Dst int32
SrcPort uint16
DstPort uint16
}
// that is how we mimic a slice
type ByteSliceA struct {
Addr *A
Len int
Cap int
}
func main() {
// structure with some data
a := A{0x04030201,0x08070605,0x0A09, 0x0C0B}
// create a slice structure
sb := &ByteSliceA{&a, 12, 12} // struct is 12 bytes long, e.g. unsafe.Sizeof(a) is 12
// take a pointer of our slice mimicking struct and cast *[]byte on it:
var byteSlice []byte = *(*[]byte)(unsafe.Pointer(sb))
fmt.Printf("%v\n", byteSlice)
}
Ausgabe:
[1 2 3 4 5 6 7 8 9 10 11 12]
package main
import (
"crypto/sha1"
"fmt"
"encoding/binary"
"bytes"
)
type myStruct struct {
ID [10]byte
Data [10]byte
}
func main() {
var bin_buf bytes.Buffer
x := myStruct{"1", "Hello"}
binary.Write(&bin_buf, binary.BigEndian, x)
fmt.Printf("% x", sha1.Sum(bin_buf.Bytes()))
}
binary.Write verwendet eine Struktur, deren Datentyp einem Speicher mit fester Länge zugewiesen ist.
Serialisierung ist wahrscheinlich die richtige Antwort.
Aber wenn Sie der Unsicherheit zustimmen und die Struktur tatsächlich als Byte lesen müssen, ist die Verwendung von Byte Array Speicherdarstellung möglicherweise etwas besser als die Verwendung von Byte Slice interne Struktur.
type Struct struct {
Src int32
Dst int32
SrcPort uint16
DstPort uint16
}
const sz = int(unsafe.SizeOf(Struct{}))
var asByteSlice []byte = (*(*[sz]byte)(unsafe.Pointer(&struct_value)))[:]
Funktioniert und bietet Schreib-/Leseansicht in struct, zero-copy. Zwei "unsichere" sollten genug andeuten, dass es schlecht brechen kann.
Benutze einfach json marshal - das ist ein sehr einfacher Weg.
newFsConfig := dao.ConfigEntity{EnterpriseId:"testing"}
newFsConfigBytes, _ := json.Marshal(newFsConfig)