MST

星途 面试题库

面试题:Go语言中复杂数据类型参数传递分析

假设有一个结构体类型`Person`,包含`name string`和`age int`两个字段,并且有一个函数`func modifyPerson(p Person)`。当向`modifyPerson`函数传递一个`Person`类型的变量时,函数内部对`p`的修改会影响到原变量吗?为什么?如果想要在函数内部修改原变量,应该如何处理?另外,分析如果`Person`结构体中嵌套了一个切片类型的字段,传递和修改该结构体时会发生什么情况。
22.4万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 函数内部对p的修改不会影响到原变量
    • 在Go语言中,函数参数传递是值传递。当调用modifyPerson(p Person)函数时,会将原Person变量的值复制一份传递给函数内部的p。所以函数内部对p的修改,修改的是这个副本,而不是原变量。
  2. 想要在函数内部修改原变量的处理方式
    • 可以通过传递指针来实现。将函数定义修改为func modifyPerson(p *Person),调用函数时传递Person变量的指针,例如:
    type Person struct {
        name string
        age  int
    }
    func modifyPerson(p *Person) {
        p.name = "newName"
        p.age = 20
    }
    func main() {
        var p Person = Person{name: "oldName", age: 18}
        modifyPerson(&p)
        println(p.name)
        println(p.name)
    }
    
  3. 如果Person结构体中嵌套了一个切片类型的字段,传递和修改该结构体时的情况
    • 当传递包含切片字段的Person结构体时,仍然是值传递,即结构体的副本被传递到函数内部。
    • 但是对于切片类型,切片本身是一个描述底层数组的结构体(包含指向底层数组的指针、切片长度和容量)。所以当函数内部修改切片的内容(例如添加、删除元素,修改元素值)时,会影响到底层数组,因为切片的指针指向的是同一个底层数组。而如果在函数内部重新给切片字段赋值(例如p.sliceField = []int{1, 2, 3}),这只是修改了副本中切片结构体的指针,不会影响原变量中的切片。例如:
    type Person struct {
        name    string
        age     int
        sliceField []int
    }
    func modifyPerson(p Person) {
        p.sliceField[0] = 100 // 会影响原切片内容,因为指向同一个底层数组
        p.sliceField = []int{1, 2, 3} // 不会影响原变量中的切片,只是修改了副本的切片指针
    }