2 回答

TA貢獻(xiàn)1864條經(jīng)驗(yàn) 獲得超2個(gè)贊
您首先轉(zhuǎn)換為具有可以適合您的數(shù)據(jù)的靜態(tài)長度的類型的數(shù)組,然后將該數(shù)組切片為正確的長度和容量。
mapSlice := (*[1 << 30]float32)(unsafe.Pointer(&mmap[0]))[:n:n]

TA貢獻(xiàn)1797條經(jīng)驗(yàn) 獲得超4個(gè)贊
不幸的是,在您的情況下,您無法獲得指向數(shù)組的指針。這是因?yàn)閚它不是一個(gè)常數(shù)值(即它是在運(yùn)行時(shí)用 確定的fileSize/4)。(注意如果fileSize是常數(shù),你可以得到一個(gè)數(shù)組。)
雖然有安全和不安全的選擇。
安全的,或者有些人可能稱之為“正確”的方式——這需要一個(gè)副本,但你可以控制字節(jié)序。這是一個(gè)例子:
import (
"encoding/binary"
"bytes"
"unsafe" // optional
)
const SIZE_FLOAT32 = unsafe.Sizeof(float32(0)) // or 4
bufRdr := bytes.NewReader(mmap)
mapSlice := make([]float32, len(mmap)/SIZE_FLOAT32) // = fileSize/4
err := binary.Read(bufRdr, binary.LittleEndian, mapSlice) // could pass &mapSlice instead of mapSlice: same result.
// mapSlice now can be used like the mapArray you wanted.
有幾種方法可以不安全地做到這一點(diǎn),但在 Go 1.17 中它非常簡單。
mapSlice := unsafe.Slice((*float32)(unsafe.Pointer(&mmap[0])), len(mmap)/SIZE_FLOAT32)
你也可以使用reflect.SliceHeader. 為了防止垃圾收集器問題,這里有很多細(xì)微差別需要注意:
var mapSlice []float32 // mapSlice := []float32{} also works (important thing is that len and cap are 0)
// newSh and oldSh are here for readability (i.e. inlining these variables is ok, but makes things less readable IMO)
newSh := (*reflect.SliceHeader)(unsafe.Pointer(&mapSlice))
oldSh := (*reflect.SliceHeader)(unsafe.Pointer(&mmap))
// Note: order of assigning Data, Cap, Len is important (due to GC)
newSh.Data = oldSh.Data
newSh.Cap = oldSh.Cap/SIZE_FLOAT32
newSh.Len = oldSh.Len/SIZE_FLOAT32
runtime.KeepAlive(mmap) // ensure `mmap` is not freed up until this point.
unsafe@JimB 的回答中給出了我能想到的最后一種方法——將 anmmap轉(zhuǎn)換為Dataan unsafe.Pointer,然后將其轉(zhuǎn)換為一個(gè)任意大的指向數(shù)組的指針,最后將該數(shù)組切片指定為所需的大小和容量。
添加回答
舉報(bào)