2016-11-16 102 views
1

查找可以在golang中声明的集合的最大长度值我正在面对错误“panic:runtime error:makeslice:len out of range”,同时为大值创建动态数组使用“make()”的长度。使用make()

例如。

arr := make([]int, length) //length is a dynamic value 

我知道,这个问题已经在这里提出(Maximum length of a slice in Go)。 但是,make方法不支持golang中“int”数据类型的最大值。它们根据(大小)struct类型消耗长度值。 是否有预定义的API可用于查找可以在golang中声明的集合的最大长度值?

如:

maxInt := int(^uint(0) >> 1) 

arr := make([]struct{}, maxInt-1) //accepted 
arr := make([]int, maxInt-1) //throw error 
+4

@Volker对于你的问题,是的!这是可行的。 Golang使用函数maxSliceCap [go1.7/src/runtime/slice.go:32]验证len和cap。有API来获取运行时信息。虽然这可以通过使用延迟功能来捕获恐慌并恢复,但我们可以使用一种简单易用的API。问题是,是否有任何暴露的API会有所帮助。 – Spartan

+1

@Spartan这只是_hard_ _upper_ _limits_!不能保证实际上将有足够的空闲内存来分配此片。 _MaxMem不是实际可用的或甚至物理上存在的RAM。但你是对的:如果这是OP的问题,那我就纠正了。 – Volker

回答

2

如果你真的想要一个切片的最大长度,你可以复制从运行时组件所使用的算法。这将以切片元素为例来确定其大小,并返回该值类型的最大切片容量。

func maxSliceCap(i interface{}) int { 
    _64bit := uintptr(1 << (^uintptr(0) >> 63)/2) 

    var goosWindows, goosDarwin, goarchArm64 uintptr 
    switch runtime.GOOS { 
    case "darwin": 
     goosDarwin = 1 
    case "windows": 
     goosWindows = 1 
    } 

    switch runtime.GOARCH { 
    case "arm64": 
     goarchArm64 = 1 
    } 

    heapMapBits := (_64bit*goosWindows)*35 + (_64bit*(1-goosWindows)*(1-goosDarwin*goarchArm64))*39 + goosDarwin*goarchArm64*31 + (1-_64bit)*32 
    maxMem := uintptr(1<<heapMapBits - 1) 

    elemSize := reflect.ValueOf(i).Type().Size() 
    max := maxMem/elemSize 

    if int(max) < 0 { 
     return 1<<31 - 1 
    } 

    return int(max) 
} 

https://play.golang.org/p/roOarwQpZL