2017-06-23 105 views
2

func foo(arr []int) intfunc foo(arr [*num*]int) int有什麼區別?func foo(arr [] int)int和func foo(arr [num] int)有什麼區別int

下面是兩個例子:

func foo1(arr [2]int) int { 
    arr[0] = 1 
    return 0 
} 

func foo2(arr []int) int { 
    arr[0] = 1 
    return 0 
} 

func main() { 
    var arr1 = [2]int{3, 4} 
    var arr2 = []int{3, 4} 
    foo1(arr1) 
    println(arr1[0])  // result is 3, so arr in foo1(arr) is a copy 
    foo2(arr2) 
    println(arr2[0])  // result is 1, so arr in foo2(arr) is not a copy, it is a reference 
} 

如果我使用foo1(arr2)foo2(arr1)我還發現,該編譯器將報告等一個錯誤「不能使用ARR2(類型[] INT)作爲型[2] INT在foo1「」的參數中,在參數foo2「」中,不能使用arr1(類型[2] int)作爲類型[] int的參數。

那麼,誰可以幫助解釋他們之間的區別或給我一些學習的鏈接?先謝謝你。

+1

學習的鏈接:Tour of Go https://tour.golang.org/welcome/1。常見問題https://golang.org/doc/faq。有效轉到https://golang.org/doc/effective_go.html。語言規範https://golang.org/ref/spec和博客https://blog.golang.org/。這個基本問題在巡迴賽中都有詳細的介紹:兩次。 – Volker

回答

5

[2]intarray[]intslice

數組和片是完全不同的類型:無法在需要片的地方傳遞數組,並且無法在需要數組的地方傳遞片。由於長度是數組類型的一部分,因此甚至不能使用長度不同的數組值,例如,對於期望[2]int的內容,不能使用[3]int類型的數組值。

Go中的所有內容都是按值傳遞的。切片也是。但是切片值是一個標頭,描述了一個支持數組的連續部分,並且切片值只包含一個指向實際存儲元素的數組的指針。切片值不包含其元素(與數組不同)。當你傳遞一個切片時,只有切片頭被複制(指向相同的後備數組),因此修改其元素會修改同一個後備數組中的元素,因此調用者將觀察這些變化。閱讀更多關於此處的信息:Are golang slices pass by value?查看切片標題中的內容:reflect.SliceHeader。與片不同,數組不是片段。一個數組值意味着它的所有元素,所以當你傳遞一個數組值時,它的所有元素都被複制,並且在它傳遞給函數的內部,你只能修改這個拷貝數組;調用者不會觀察對數組所做的更改(例如,更改其元素)。

注意,但它是很容易獲得的數組切片值,你可以簡單地使用slicing

var a [2]int = [2]int{1, 2} 
var s []int = a[:] 
fmt.Println(s) // Prints [1 2] 

推薦的博客文章:Go Slices: usage and internals

更深入地瞭解數組VS片:Why have arrays in Go?

+0

感謝您的信息和鏈接。 – user3300252

0

[2]int是一個有2個條目的固定長度數組。
[]int是一個不固定的片。

func foo1(arr [2]int)需要一個固定長度 int有2個條目的數組。 func foo2(arr []int)需要一個非固定的 int與任意數量的條目。

它們看起來很相似,但如果將int和[] int看作完全不同的結構,它可能會有所幫助。

+1

「[2] int」類型的數組有2個元素,而不是3. – icza

0

[n]T類型是n類型值的數組,T

[]T類型是T類型的元素的切片。

數組的大小是固定的。而切片是動態的。

隨着foo1該函數被調用時,數組的副本。

所以原值arr1保持不變

相關問題