MST

星途 面试题库

面试题:Go语言指针错误使用案例之指针与结构体的易错点

假设有如下Go语言结构体定义: ```go package main import "fmt" type Person struct { Name string Age int } func modifyPerson(ptr *Person) { ptr = &Person{Name: "NewName", Age: 30} } func main() { p := Person{Name: "OldName", Age: 20} modifyPerson(&p) fmt.Printf("Name: %s, Age: %d", p.Name, p.Age) } ``` 这段代码执行后输出并非预期的修改后的值,请分析原因,并给出正确的修改方式,同时阐述Go语言指针在结构体传递中的特性。
36.5万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

原因分析

modifyPerson 函数中,虽然参数 ptr 是指针类型,但 ptr = &Person{Name: "NewName", Age: 30} 这行代码只是修改了 ptr 这个局部指针变量,使其指向了一个新的 Person 结构体实例。然而,这个修改并没有影响到调用函数时传入的原始指针,因此原始的 p 结构体并没有被修改。

正确修改方式

要正确修改原始的 Person 结构体,需要直接通过指针修改其成员,而不是重新赋值指针。修改后的代码如下:

package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func modifyPerson(ptr *Person) {
    ptr.Name = "NewName"
    ptr.Age = 30
}

func main() {
    p := Person{Name: "OldName", Age: 20}
    modifyPerson(&p)
    fmt.Printf("Name: %s, Age: %d", p.Name, p.Age)
}

Go语言指针在结构体传递中的特性

  1. 值传递:在Go语言中,函数参数传递是值传递。当传递结构体指针时,实际上传递的是指针的值(即内存地址)的一份拷贝。这意味着在函数内部对指针变量本身的修改(如重新赋值)不会影响到外部的原始指针。
  2. 间接访问:通过传递结构体指针,可以在函数内部间接访问和修改原始结构体的成员。这种方式可以避免在传递大结构体时的性能开销,因为只需要传递一个指针(通常是8字节,64位系统)而不是整个结构体的副本。
  3. 内存管理:使用指针传递结构体时,需要注意内存的生命周期。如果在函数内部创建新的结构体并将指针返回,调用者需要确保在适当的时候释放内存(Go语言的垃圾回收机制会自动处理大部分情况)。