面试题答案
一键面试- 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 }
- 切片传递时的安全性体现
- 结构传递:虽然切片是引用类型,但在函数调用时,传递的是切片结构的副本。切片结构包含三个部分:指向底层数组的指针、切片的长度和容量。传递副本保证了函数内部对切片结构的直接修改(如修改长度、容量相关的操作)不会影响到外部切片结构。例如:
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语言在函数实参传递过程中保障了一定程度的安全性。