[]float32
を[]byte
にキャストしたい。けど方法がわからない。
mattnさんがunsafeを使って、str→[]byteの方法を紹介してくれています。これが応用できないか?
float32だと分かりにくいので、uint16→byteで試してみます。gore上でやってます, 513, 1027という数値の配列をリトルエンディアンでうまくバイトごとに取れると、1, 2, 3, 4という配列になるはずなので、それを目標に。
unsafeで[]uint16を[]byteに
gore> a := []uint16{513, 1027} // []uint16{0x201, 0x403}
gore> b := *(*[]byte)(unsafe.Pointer(&a[0]))
unexpected fault address 0x4030201
fatal error: fault
[signal 0xa code=0x2 addr=0x4030201 pc=0x5ced6]
だめでした。確かに、スライスは長さ情報を持つオブジェクトで、まったく別のものなのでダメかもしれません。
unsafeで[]uint16を[4]byteに
gore> a := []uint16{513, 1027} // []uint16{0x201, 0x403}
gore> b := *(*[4]byte)(unsafe.Pointer(&a[0]))
[4]uint8{0x1, 0x2, 0x3, 0x4}
今度は長さ指定の配列に。今度はうまくいったように見えます。固定長配列の[4]byte
から[]byte
へのキャストは問題なくコピーなしでいけます。じゃあa[0]を変更してみますか。
gore> a[0] = 0
0x0
gore> b
[4]uint8{0x1, 0x2, 0x3, 0x4}
あれ、変わってない。newされてコピーされてしまったようですね。
なお、元データの方を固定長配列にしても結果は同じでした。
今回はコピーがあろうがなかろうが、時間のペナルティはあるもののロジックは正しく動くので(union的にその後お互いにやりとりすることはなくて、OpenGLで送っちゃっておしまいなので)、このコピーは許容範囲ということにしておいてとりあえず作業は進めますが、もしゼロコピー化する方法が分かる方がいらっしゃいましたら教えて下さい。