Golang 的参数传递、引用类型
Golang 的参数传递、引用类型
Go 语言中所有的传参都是值传递(传值),都是一个副本,一个拷贝。因为拷 贝的内容有时候是非引用类型(int、string、struct 等这些),这样就在函 数中就无法修改原内容数据;有的是引用类型(指针、map、slice、chan 等这 些),这样就可以修改原内容数据。
Golang 的引用类型包括 slice、map 和 channel。它们有复杂的内部结构,除 了申请内存外,还需要初始化相关属性。内置函数 new 计算类型大小,为其分 配零值内存,返回指针。而 make 会被编译器翻译成具体的创建函数,由其分 配内存和初始化成员结构,返回对象而非指针。
在Go语言中,参数传递是通过值传递的方式进行的,即使是对于引用类型(如切片、映射、通道、接口、以及指向结构体、数组等的指针)也是如此。然而,理解这一点时需要注意的是,虽然传递的是值的副本,但如果这个值是引用类型的,那么副本本身仍然指向原始数据。这意味着通过这个副本(即函数内的参数),你可以访问和修改原始数据。
示例:引用类型(切片)的参数传递
考虑以下示例,我们有一个切片,我们将其作为参数传递给一个函数,然后在函数内部修改它:
package main
import "fmt"
// 修改切片中的元素
func modifySlice(s []int, index int, value int) {
// 直接通过参数s(切片副本的引用)修改原始切片
s[index] = value
}
func main() {
mySlice := []int{1, 2, 3, 4, 5}
fmt.Println("原始切片:", mySlice)
// 调用函数,修改切片中的元素
modifySlice(mySlice, 2, 100)
// 原始切片被修改了
fmt.Println("修改后的切片:", mySlice)
}
输出将会是:
原始切片: [1 2 3 4 5]
修改后的切片: [1 2 100 4 5]
在这个例子中,尽管我们传递的是mySlice
的一个副本给modifySlice
函数,但由于切片是引用类型,这个副本和原始切片都指向了同一个底层数组。因此,当我们通过函数内的s
参数修改切片时,实际上修改的是原始切片mySlice
。
结论
在Go中,所有类型的参数都是按值传递的。对于引用类型,这个“值”是一个指向数据的指针(或引用),所以你可以通过函数参数访问和修改原始数据。这与其他一些语言(如C++或Java)中通过引用传递对象或数组的方式在效果上相似,但Go的实现方式更加清晰和一致。