search
LoginSignup
12
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

Organization

【緩募】Golangでスライスの型のキャストをする方法が知りたい

[]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で送っちゃっておしまいなので)、このコピーは許容範囲ということにしておいてとりあえず作業は進めますが、もしゼロコピー化する方法が分かる方がいらっしゃいましたら教えて下さい。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
12
Help us understand the problem. What are the problem?