13
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-11-19

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

13
12
5

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
  3. You can use dark theme
What you can do with signing up
13
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?