MST

星途 面试题库

面试题:Go中函数实参传递安全性保障的基本原理

请简要阐述Go语言在函数实参传递过程中,是如何保障安全性的?例如在传递切片时,安全性体现在哪些方面?
31.0万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. Go语言函数实参传递的安全性保障基础
    • Go语言函数实参传递遵循值传递原则。这意味着传递给函数的是实参的副本,而不是实参本身。这样在函数内部对形参的修改不会影响到函数外部的实参。例如:
    package main
    
    import "fmt"
    
    func modifyValue(num int) {
        num = num + 1
    }
    
    func main() {
        value := 10
        modifyValue(value)
        fmt.Println(value) // 输出10,说明函数内部对num的修改没有影响到外部的value
    }
    
  2. 切片传递时的安全性体现
    • 结构传递:虽然切片是引用类型,但在函数调用时,传递的是切片结构的副本。切片结构包含三个部分:指向底层数组的指针、切片的长度和容量。传递副本保证了函数内部对切片结构的直接修改(如修改长度、容量相关的操作)不会影响到外部切片结构。例如:
    package main
    
    import "fmt"
    
    func modifySlice(slice []int) {
        // 这里试图修改切片结构长度,不会影响外部切片
        newSlice := make([]int, len(slice)+1)
        copy(newSlice, slice)
        slice = newSlice
    }
    
    func main() {
        mySlice := []int{1, 2, 3}
        modifySlice(mySlice)
        fmt.Println(mySlice) // 输出[1 2 3],说明切片结构未被函数内部修改
    }
    
    • 底层数组共享控制:切片共享底层数组,当函数内部通过切片修改底层数组元素时,会影响到外部使用同一底层数组的切片。但这种影响是预期内的共享数据的修改。为了保证安全性,可以在函数内部需要修改时创建新的底层数组(例如通过append函数,在容量不足时会创建新的底层数组),从而避免对外部共享底层数组的意外修改。例如:
    package main
    
    import "fmt"
    
    func safeModifySlice(slice []int) {
        newSlice := append([]int{}, slice...) // 创建新的底层数组
        newSlice[0] = 100
        fmt.Println(newSlice)
    }
    
    func main() {
        mySlice := []int{1, 2, 3}
        safeModifySlice(mySlice)
        fmt.Println(mySlice) // 输出[1 2 3],说明原切片不受影响
    }
    

通过值传递和对切片结构与底层数组的合理操作,Go语言在函数实参传递过程中保障了一定程度的安全性。