英文:
Finding the maximum length value of a collection that can be declared in golang using make()
问题
我遇到了一个错误:"panic: runtime error: makeslice: len out of range",这是在创建一个动态数组时出现的,当长度的值很大时使用"make()"函数。
例如:
arr := make([]int, length) // length是一个动态值
我知道,这个问题已经在这里提问过了(https://stackoverflow.com/questions/27647737/maximum-length-of-a-slice-in-go)。
但是,make方法不支持golang中"int"数据类型的最大值。它们根据(结构体类型的)大小来消耗长度值。
在golang中是否有任何预定义的API可以找到可以声明的集合长度值的最大值?
例如:
maxInt := int(^uint(0) >> 1)
arr := make([]struct{}, maxInt-1) // 可以接受
arr := make([]int, maxInt-1) // 报错
英文:
I'm facing the error "panic: runtime error: makeslice: len out of range", while creating a dynamic array, for large values of length using "make()".
eg.
arr := make([]int, length) //length is a dynamic value
I know, this question was already asked here (https://stackoverflow.com/questions/27647737/maximum-length-of-a-slice-in-go).
But, the make method does not support maximum value of the "int" datatype in golang. They consume the length value based on (size of) struct type.
Is there any predefined APIs available to find maximum of the length value of a collection that can be declared in golang ?
Eg:
maxInt := int(^uint(0) >> 1)
arr := make([]struct{}, maxInt-1) //accepted
arr := make([]int, maxInt-1) //throw error
答案1
得分: 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
英文:
If you really want the max length of a slice, you can copy the algorithm used from the runtime package. This will take an example of the slice element to determine its size, and return the maximum slice capacity for that value type.
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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论