2016-11-16 22 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