Finding the maximum length value of a collection that can be declared in golang using make()

huangapple go评论124阅读模式
英文:

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 &lt;&lt; (^uintptr(0) &gt;&gt; 63) / 2)

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

	switch runtime.GOARCH {
	case &quot;arm64&quot;:
		goarchArm64 = 1
	}

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

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

	if int(max) &lt; 0 {
		return 1&lt;&lt;31 - 1
	}

	return int(max)
}

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

huangapple
  • 本文由 发表于 2016年11月16日 19:06:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/40630562.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定