2013-05-02 32 views
15

私は定義した構造体のインスタンスを持っています。これをバイト配列に変換したいと思います。私は[] byte(my_struct)を試しましたが、うまくいきませんでした。また、私はbinary packageを指摘しましたが、私はどの機能を使うべきか、どうすればそれを使うべきかはわかりません。例をお聞かせください。Goでは、構造体をバイト配列に変換するにはどうすればよいですか?

答えて

14

Cがこれを処理する方法のようにしたいと思います。それを行う方法はありません。構造体のバイトとの間で独自のシリアライゼーションとデシリアライゼーションを定義する必要があります。バイナリパッケージは、構造体のフィールド をバイト配列にエンコードするのに役立ちますが、構造体のフィールドを保持するバイト配列の長さとオフセットを指定する責任があります。

その他のオプションは、エンコードパッケージの1つ、つまりgobまたはjsonのようなhttp://golang.org/pkg/encoding/を使用することです。

EDIT:あなたのコメントで言うように、あなたがハッシュを作るためにこれをしたいので

行うにeasisest事はそうのような[]byte(fmt.Sprintf("%v", struct))を使用している:http://play.golang.org/p/yY8mSdZ_kf

+0

ありがとうございました。私はこれをやろうとしている理由は、私の構造体のハッシュ(私はSHA - 256を使用しようとしているが、それは別のものかもしれない)を得ることができるということです。あなたはこれを行う簡単な方法を知っていますか? – abw333

+1

私はあなたが望むことを簡単に行うための答えを編集しました。 –

+0

もう一度ありがとう。私はそれをやろうとしましたが、次のエラーメッセージが表示されます。 "単一値コンテキストでの複数値fmt.Printf()"。なぜそれが起こっているのか知っていますか? – abw333

2

は、あなたがそれをBSONするシリアライズと考えたことがありますか?あなたが代わりに文字列のバイトバッファを使用する必要がありますhttp://labix.org/gobson

7

、他の提案の方法は、可変長のSHA1を作成し、SHA1の標準長は20バイト(160ビット)

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

はそれを自分で試してみてくださいする必要があります。 http://play.golang.org/p/8YuM6VIlLV

これは本当に簡単な方法です。

+1

リンクのみの回答は推奨されていません。 –

+0

ありがとう、私はこれを編集します。私の最初のコメントでした。 –

+7

'myStruct'は固定サイズではないので、このようには見えません。 https://play.golang。org/p/IGA_lgRVNX –

1

可能な解決策の1つは"encoding/gob"標準パッケージです。 gobパッケージは、任意の構造体をバイト配列にエンコードし、その配列をデコードして構造体に戻すことができるエンコーダ/デコーダを作成します。素晴らしい投稿、hereがあります。

他の人も指摘しているように、構造体は性質上不明なサイズを持ち、バイト配列に変換できないため、このようなパッケージを使用する必要があります。

いくつかのコードと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) 
} 
関連する問題