提问人:SammyO 提问时间:11/25/2017 最后编辑:SammyO 更新时间:11/25/2017 访问量:6274
请解释 golang 类型是否按值传递
Please explain if golang types pass by value
问:
我正在尝试制作一个非常简单的程序来修改数组,但是如果我将它们转换为类型,会遇到一些有趣的行为。https://play.golang.org/p/KC7mqmHuLw似乎如果我有一个数组,go 通过引用传递,但如果我有一个类型,那么 go 通过值传递。这是正确的吗?
我有两个变量 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
}
答:
数组是单一类型的元素的编号序列,称为 元素类型。
切片是基础的连续段的描述符 数组,并提供对来自该元素的编号序列的访问 数组。
在函数调用中,函数值和参数的计算结果为 通常的顺序。评估后,调用的参数 按值传递给函数,然后调用函数开始 执行。函数的返回参数按值传递 当函数返回时,返回到调用函数。
type cT [3]int b := []int{1, 2, 3} c := cT{1, 2, 3}
我有两个变量,并且 都是 3 个整数的数组
b
c
不,你没有!
b
是长度为 () 3 且容量为 () 3 的切片,是 () 3 的数组。int
len(b)
cap(b)
c
len(c)
int
在 Go 中,所有参数都是按值传递的。 作为切片描述符传递,作为数组传递。切片描述符是具有切片长度和容量的 a,以及指向基础数组的指针。b
c
struct
评论
查看评论:
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)
}
- 当我将 slice 称为 ref 时,我在这里简化了细节 https://blog.golang.org/go-slices-usage-and-internals
评论
manglePC(&c)
func manglePC(row *cT) { (*row)[2] = 0 }