1

我試圖製作一個非常簡單的程序來修改數組,但是如果將它們轉換爲類型,會遇到一些有趣的行爲。 https://play.golang.org/p/KC7mqmHuLw看來,如果我有一個數組去傳遞參考,但如果我有一個類型,然後去傳遞值。它是否正確?請解釋一下golang類型是否按值傳遞

我有兩個變量b和c,都是3個整數數組,但c是cT類型,在其他方面它們應該是相同的。我可以將值分配爲b[0]=-1c[0]=-1,但是如果將這些數組作爲參數傳遞給函數,則它們的作用非常不同。

的程序的輸出是:

B之前:[1 2 3]

在C之前:[1 2 3]

* B後:[-1 2 0 ]

* c之後:[-1 2 3]

*什麼? c:[-1 2 0]

我最初的假設是,「在b之後」和「在c之後」應該是相同的。我是在做一些不正確的事情,還是我正確地將類型傳遞給函數的值(即在傳遞給函數之前創建變量的副本)?

package main 

import "fmt" 

type cT [3]int 

func main() { 
    b := []int{1, 2, 3} 
    c := cT{1, 2, 3} 

    fmt.Println("before b:", b) 
    fmt.Println("before c:", c) 

    b[0] = -1 
    c[0] = -1 
    mangleB(b) // ignore return value 
    mangleC(c) // ignore return value 

    fmt.Println("*after b:", b) 
    fmt.Println("*after c:", c) 

    c = mangleC(c)  
    fmt.Println("*what? c:", c)  
} 

func mangleB(row []int) []int { 
    row[2] = 0 
    return row 
} 

func mangleC(row cT) cT{ 
    row[2] = 0 
    return row 
} 
+0

OK,感謝您的幫助!通過提供的信息,我得到了我想要的效果,通過傳遞類型'manglePC(&c)'的引用並將函數更改爲:func manglePC(row * cT){* row} [2] = 0 }' – SammyO

回答

2

The Go Programming Language Specification

Array types

數組是一種單一類型的元素的編號序列,稱爲 元素類型。

Slice types

切片是用於底層 陣列的連續區段的描述符並提供訪問從 數組元素的編號序列。

Calls

在一個函數調用,該函數值和參數在 通常的順序進行評估。評估完成後,呼叫 的參數將按值傳遞給函數,被調用的函數將開始執行 。當函數返回時,函數的返回參數通過值 傳回給調用函數。


type cT [3]int 

b := []int{1, 2, 3} 
c := cT{1, 2, 3} 

我有兩個變量,bc,都是3個整數


不,你不數組!

b切片int與長度(len(b))3和容量(cap(b))3,c是(len(c))3 int一個陣列

在Go中,所有參數都按值傳遞。 b作爲切片描述符傳遞,c作爲數組傳遞。切片描述符是具有切片長度和容量的struct以及指向底層數組的指針。

0

看評論:

func main() { 
    b := []int{1, 2, 3} // slice 
    c := cT{1, 2, 3} // array 

    fmt.Println("before b:", b) 
    fmt.Println("before c:", c) 

    b[0] = -1 
    c[0] = -1 

    // passing in a slice which you can think of as ref to array 
    // pass by value, and it is copy of ref to array 
    mangleB(b) // ignore return value 

    // passing in copy of array (pass by value) 
    // yes full shallow copy of array 
    mangleC(c) // ignore return value 
    // if you ignore return modifications are lost 

    fmt.Println("*after b:", b) 
    fmt.Println("*after c:", c) 

    // return value is modified array 
    c = mangleC(c) 
    // c now copy of array from line 24 

    fmt.Println("*what? c:", c) 
} 

https://play.golang.org/p/OAaCMhc-Ug