Go:如何将unsafe.Pointer转换为指向未知长度的数组的指针?

时间:2016-08-29 21:19:20

标签: arrays go mmap

我正在尝试编写一个Go程序,它使用mmap将包含float32值的非常大的文件映射到内存中。这是我的尝试(灵感来自previous answer,为简洁省略了错误处理):

package main

import (
    "fmt"
    "os"
    "syscall"
    "unsafe"
)

func main() {
    fileName := "test.dat"
    info, _ := os.Stat(fileName)
    fileSize := info.Size()
    n := int(fileSize / 4)

    mapFile, _ := os.Open(fileName)
    defer mapFile.Close()
    mmap, _ := syscall.Mmap(int(mapFile.Fd()), 0, int(fileSize),
        syscall.PROT_READ, syscall.MAP_SHARED)
    defer syscall.Munmap(mmap)
    mapArray := (*[n]float32)(unsafe.Pointer(&mmap[0]))

    for i := 0; i < n; i++ {
        fmt.Println(mapArray[i])
    }
}

此操作失败,并显示以下错误消息:

./main.go:21: non-constant array bound n

由于n由文件的长度决定(在编译时不知道),所以我无法用强制转换中的常量值替换n。如何将mmap转换为float32值的数组(或切片)?

1 个答案:

答案 0 :(得分:2)

首先转换为具有适合您数据的静态长度的类型数组,然后将该数组切割为正确的长度和容量。

mapSlice := (*[1 << 30]float32)(unsafe.Pointer(&mmap[0]))[:n:n]