Golang 的参数传递、引用类型

发布于 1周前 作者 wuwangju 最后一次编辑是 5天前 来自 问答

Golang 的参数传递、引用类型

Go 语言中所有的传参都是值传递(传值),都是一个副本,一个拷贝。因为拷 贝的内容有时候是非引用类型(int、string、struct 等这些),这样就在函 数中就无法修改原内容数据;有的是引用类型(指针、map、slice、chan 等这 些),这样就可以修改原内容数据。

Golang 的引用类型包括 slice、map 和 channel。它们有复杂的内部结构,除 了申请内存外,还需要初始化相关属性。内置函数 new 计算类型大小,为其分 配零值内存,返回指针。而 make 会被编译器翻译成具体的创建函数,由其分 配内存和初始化成员结构,返回对象而非指针。

1 回复

在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的实现方式更加清晰和一致。

回到顶部