MST

星途 面试题库

面试题:Go函数调用中的值传递与引用传递理解

在Go语言函数调用中,详细说明值传递和引用传递的区别,并举例说明在函数调用时,哪些数据类型是值传递,哪些类似引用传递。
47.4万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

值传递和引用传递的区别

  1. 值传递
    • 在值传递时,函数接收的是调用者传递的实际值的副本。函数内部对这个副本的任何修改,都不会影响调用者传入的原始值。
    • 这意味着函数有自己独立的内存空间来存储这个副本,对副本的操作与原始数据无关。
  2. 引用传递
    • 引用传递时,函数接收的是调用者传递的数据的内存地址(或类似对数据的引用)。函数内部对通过这个引用访问到的数据的修改,会直接影响调用者传入的原始数据。
    • 函数和调用者共享相同的数据内存空间,操作的是同一份数据。

数据类型传递方式示例

  1. 值传递的数据类型
    • 基本数据类型:如 intfloat64boolstring 等。
    package main
    
    import "fmt"
    
    func changeValue(num int) {
        num = num + 10
    }
    
    func main() {
        a := 5
        changeValue(a)
        fmt.Println(a) // 输出 5,函数内部修改未影响原始值
    }
    
    • 数组:数组在Go语言中也是值传递。
    package main
    
    import "fmt"
    
    func changeArray(arr [3]int) {
        arr[0] = 100
    }
    
    func main() {
        myArr := [3]int{1, 2, 3}
        changeArray(myArr)
        fmt.Println(myArr) // 输出 [1 2 3],函数内部修改未影响原始数组
    }
    
  2. 类似引用传递的数据类型
    • 指针:通过传递指针,函数可以修改指针指向的数据。
    package main
    
    import "fmt"
    
    func changeValueWithPointer(num *int) {
        *num = *num + 10
    }
    
    func main() {
        a := 5
        changeValueWithPointer(&a)
        fmt.Println(a) // 输出 15,函数内部通过指针修改了原始值
    }
    
    • 切片(Slice):切片虽然在语法上看起来像数组,但它的底层实现类似指针,传递切片给函数时,函数内部对切片内容的修改会影响原始切片。
    package main
    
    import "fmt"
    
    func changeSlice(slc []int) {
        slc[0] = 100
    }
    
    func main() {
        mySlc := []int{1, 2, 3}
        changeSlice(mySlc)
        fmt.Println(mySlc) // 输出 [100 2 3],函数内部修改影响了原始切片
    }
    
    • 映射(Map):映射也是类似引用传递,函数内部对映射的修改会影响原始映射。
    package main
    
    import "fmt"
    
    func changeMap(m map[string]int) {
        m["key"] = 200
    }
    
    func main() {
        myMap := map[string]int{"key": 100}
        changeMap(myMap)
        fmt.Println(myMap) // 输出 map[key:200],函数内部修改影响了原始映射
    }
    
    • 通道(Channel):通道传递给函数时,函数对通道的操作会影响原始通道,类似于引用传递。
    package main
    
    import "fmt"
    
    func sendData(ch chan int) {
        ch <- 42
    }
    
    func main() {
        myCh := make(chan int)
        go sendData(myCh)
        data := <-myCh
        fmt.Println(data) // 输出 42,函数向通道发送数据影响了原始通道
        close(myCh)
    }