7.3 结构体指针

本篇学习 Go 结构体指针、值拷贝差异与指针接收者用法,并能正确修改结构体字段。

字数 555 字

结构体指针

概念说明

结构体作为函数参数或方法接收者时,既可以按值传递,也可以用指针传递。
如果希望在函数/方法内部修改原结构体,通常需要使用结构体指针。

语法/规则

  1. 值参数(Student)会复制一份数据,修改不会影响外部原值。
  2. 指针参数(*Student)传的是地址,修改会影响外部原值。
  3. 值接收者方法(func (s Student) ...)修改的是副本。
  4. 指针接收者方法(func (s *Student) ...)可修改原结构体字段。
  5. 调用指针接收者方法时,Go 会自动帮你取地址(前提是可寻址值)。

函数参数示例(值参数 vs 指针参数)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

import "fmt"

type Student struct {
	Name string
	Age  int
}

func SetAgeByValue(info Student, age int) {
	info.Age = age
}

func SetAgeByPointer(info *Student, age int) {
	info.Age = age
}

func main() {
	student := Student{
		Name: "阿斌",
		Age:  21,
	}

	fmt.Println(student.Age)
	SetAgeByValue(student, 18)
	fmt.Println(student.Age)
	SetAgeByPointer(&student, 17)
	fmt.Println(student.Age)
}

输出结果:

1
2
3
21
21
17

方法接收者示例(值接收者 vs 指针接收者)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

import "fmt"

type Student struct {
	Name string
	Age  int
}

func (s Student) SetAge(age int) {
	s.Age = age
}

func (s *Student) SetAgeByPointer(age int) {
	s.Age = age
}

func main() {
	student := Student{
		Name: "阿斌",
		Age:  21,
	}

	student.SetAge(18)
	fmt.Println(student.Age)

	student.SetAgeByPointer(18)
	fmt.Println(student.Age)
}

输出结果:

1
2
21
18

常见错误

  1. 希望修改原结构体却使用了值参数或值接收者,导致修改无效。
  2. 忘记区分“读场景”和“改场景”,所有方法都用值接收者或都用指针接收者。
  3. nil 结构体指针直接访问字段,可能触发运行时 panic。
使用 Hugo 构建
主题 StackJimmy 设计 由 Hobin 魔改
载入天数...载入时分秒...
发表了 0 篇文章 · 发表了 46 篇笔记 · 总计 2 万 5 千字(其中笔记 25104 字)