我正在尝试创建一个非常简单的程序来修改数组,但是如果我将它们转换为类型则会遇到一些有趣的行为。 https://play.golang.org/p/KC7mqmHuLw看来,如果我有一个数组,则通过引用传递,但如果我有一个类型,则按值传递。这是对的吗?
我有两个变量b和c,两个都是3个整数的数组,但c是cT类型,在其他方面它们应该是相同的。我可以将值指定为b[0]=-1
和c[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 :(得分:3)
The Go Programming Language Specification
数组是单个类型的元素的编号序列,称为 元素类型。
切片是底层的连续段的描述符 数组并提供对该数字的编号序列的访问 阵列。
在函数调用中,将计算函数值和参数 通常的顺序。在评估它们之后,调用的参数 通过值传递给函数,并且被调用的函数开始 执行。函数的返回参数按值传递 当函数返回时返回调用函数。
type cT [3]int b := []int{1, 2, 3} c := cT{1, 2, 3}
我有两个变量,
b
和c
,都是3个整数的数组
不,你不要!
b
是int
的切片,其长度为len(b)
)3,容量为cap(b)
)3,c
是(len(c)
)3 int
。
在Go中,所有参数都按值传递。 b
作为切片描述符传递,c
作为数组传递。切片描述符是具有切片长度和容量的struct
,以及指向底层数组的指针。
答案 1 :(得分: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)
}