2013-05-02 39 views
15

Tôi có một thể hiện của một cấu trúc mà tôi đã xác định và tôi muốn chuyển đổi nó thành một mảng các byte. Tôi đã thử [] byte (my_struct), nhưng điều đó không hoạt động. Ngoài ra, tôi đã được chỉ đến binary package, nhưng tôi không chắc chắn nên sử dụng chức năng nào và cách sử dụng nó. Một ví dụ sẽ được đánh giá cao.Trong Go, làm cách nào tôi có thể chuyển đổi cấu trúc thành mảng byte?

Trả lời

14

Tôi giả sử bạn muốn một cái gì đó giống như cách C xử lý việc này. Không có cách nào được xây dựng để làm điều đó. Bạn sẽ phải xác định serialization của riêng bạn và deserialization đến và từ byte cho struct của bạn. Gói nhị phân sẽ giúp bạn mã hóa các trường trong cấu trúc của bạn thành các byte mà bạn có thể thêm vào mảng byte nhưng bạn sẽ chịu trách nhiệm chỉ định độ dài và độ lệch trong mảng byte sẽ giữ các trường từ cấu trúc của bạn.

Các tùy chọn khác của bạn là sử dụng một trong các gói mã hóa: http://golang.org/pkg/encoding/ chẳng hạn như gob hoặc json.

EDIT:

Vì bạn muốn điều này để thực hiện một băm như bạn nói trong bình luận của bạn điều easisest làm là sử dụng []byte(fmt.Sprintf("%v", struct)) như vậy: http://play.golang.org/p/yY8mSdZ_kf

+0

Cảm ơn câu trả lời nhanh của bạn. Lý do tôi đang cố gắng để làm điều này là để có thể nhận được một băm (Tôi đang cố gắng sử dụng SHA-256, nhưng nó có thể là một) của cấu trúc của tôi. Bạn có biết cách làm dễ dàng hơn không? – abw333

+1

Tôi đã chỉnh sửa câu trả lời để hiển thị một cách dễ dàng để thực hiện những gì bạn muốn. –

+0

Cảm ơn bạn lần nữa. Tôi đã thử làm điều đó, nhưng tôi nhận được thông báo lỗi sau: "multiple-value fmt.Printf() trong bối cảnh giá trị đơn". Bạn có biết tại sao điều đó đang xảy ra không? – abw333

7

Bạn nên sử dụng một bộ đệm byte thay vì một chuỗi, các phương pháp gợi ý khác tạo ra một SHA1 của chiều dài thay đổi, chiều dài tiêu chuẩn SHA1 phải là 20 byte (160 bit)

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

Hãy thử nó cho mình: http://play.golang.org/p/8YuM6VIlLV

Đó là một phương pháp thực sự dễ dàng và nó hoạt động tuyệt vời.

+1

Câu trả lời chỉ liên kết không được chấp nhận. –

+0

Cảm ơn bạn Der, tôi sẽ chỉnh sửa điều này. Là bình luận đầu tiên của tôi. –

+7

Không giống như thế này hoạt động vì 'myStruct' không phải là kích thước cố định. https: //play.golang.org/p/IGA_lgRVNX –

1

Một giải pháp có thể là gói tiêu chuẩn "encoding/gob". Gói gob tạo bộ mã hóa/giải mã có thể mã hóa bất kỳ cấu trúc nào thành một mảng các byte và sau đó giải mã mảng đó trở lại thành một cấu trúc. Có một bài đăng tuyệt vời, here.

Như những người khác đã chỉ ra, cần sử dụng một gói như thế này vì cấu trúc, theo bản chất của chúng, có kích thước không xác định và không thể chuyển đổi thành mảng byte.

Tôi đã bao gồm một số mã và play.

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) 
} 
Các vấn đề liên quan