在Go

2014-12-25 29 views
7
片的最大長度

我有下面的代碼在64位Linux操作系統在4Gb的機器上運行:在Go

package main 

import (
    "fmt" 
    "math" 
) 

func main() { 
    r := make([]bool, math.MaxInt32) 

    fmt.Println("Size: ", len(r)) 
} 

當我運行此我得到:

Size: 2147483647 

如果我改變math.MaxInt32math.MaxUint32我得到:

fatal error: runtime: out of memory 

隨着math.MaxUint32片大小我跑內存不足,我期待的是,但是當我嘗試使用math.MaxInt64我得到:

panic: runtime error: makeslice: len out of range 

所以aparently我不能以大小的math.MaxInt64,這給我們帶來了我的問題創建一個切片:如果內存是不是一個問題,我無法在Go中創建最大的切片?

我記得,在Java中,原數組索引與類型int管理,因此原始數組的最大尺寸是int的最大值,如果你試圖用long這樣做會引發異常(據我記憶),這跟Go一樣嗎? Go中的切片索引綁定到一個特定的類型?

編輯:

我使用struct{}代替bool和分配math.MaxInt64元素運行測試。一切都如預期,並打印:

Size: 9223372036854775807 

所以,另外一個問題,爲什麼有兩種不同的錯誤信息時,它似乎錯誤是一樣的(沒有足夠的內存)?

每個錯誤彈出的條件是什麼?

+0

所以看來這是錯誤信息含糊,僅此而已...... :) –

回答

10

根據文檔,The elements can be addressed by integer indices 0 through len(s)-1。這意味着切片的最大容量是目標版本上默認整數的大小。

編輯:從查看源代碼,它似乎有一個安全檢查,以確保該尺寸片是在所有可能的:

func makeslice(t *slicetype, len64 int64, cap64 int64) sliceStruct { 
    // NOTE: The len > MaxMem/elemsize check here is not strictly necessary, 
    // but it produces a 'len out of range' error instead of a 'cap out of range' error 
    // when someone does make([]T, bignumber). 'cap out of range' is true too, 
    // but since the cap is only being supplied implicitly, saying len is clearer. 
    // See issue 4085. 
    len := int(len64) 
    if len64 < 0 || int64(len) != len64 || t.elem.size > 0 && uintptr(len) > maxmem/uintptr(t.elem.size) { 
     panic(errorString("makeslice: len out of range")) 
    } 

所以在這種情況下,它看起來像uintptr(len) > maxmem/uintptr(t.elem.size)所以我們不允許做這樣大小的分配。

然而,當我分配struct{}它沒有任何記憶,這個尺寸是可以的:

func main(){ 
    r := make([]struct{}, math.MaxInt64) 
    fmt.Println(len(r)) 
} 
// prints 9223372036854775807 
+0

的事情我敢肯定,我運行64位去,如果我'去版本'它打印'去版本go1.4 linux/amd64' –

+0

@SimonOroño什麼'go env'打印GOARCH? –

+0

@SimonOroño我看過Go的源代碼,我想我知道這個問題。更新我的答案。 –