Go 语言中的值类型和指针类型区别对比分析

 更新时间:2025年11月21日 09:34:13   作者:半桶水专家  
在Go语言中,值类型(如int、struct)存储实际数据,而指针类型(如*int、*struct)存储数据的内存地址,值类型是按值传递的,修改不会影响原变量,本文给大家介绍Go 语言中的值类型和指针类型,感兴趣的朋友跟随小编一起看看吧

在 Go 语言中,变量的类型可以是值类型(Value Type)或指针类型(Pointer Type)。它们的核心区别在于:存储的内容不同、内存地址的变化不同、函数传参的行为不同

下面我从本质 + 内存模型 + 例子 + 什么时候用指针 来完整解释。

✅ 一、值类型 vs 指针类型 — 本质区别

特性值类型指针类型
存储内容实际数据数据的内存地址(指向某个值)
赋值时拷贝整份数据拷贝地址(两个指针指向同一块内存)
改动是否影响原变量❌ 不影响✔ 会影响
空值无法为 nil可以为 nil
内存分配栈为主指向堆或栈都可能

✅ 二、本质理解:变量保存的是什么?

✔ 值类型(int、float、struct、array 等)

变量里保存的是“真实的数据”。

a := 10
b := a   // b 拷贝一份 10
b = 20
fmt.Println(a) // 10 (不会受到影响)

值类型总是复制一份独立的数据。

✔ 指针类型(*int、*struct、*MyType)

变量里保存的是“另一个变量的地址”。

a := 10
b := &a   // b 保存 a 的地址
*b = 20
fmt.Println(a) // 20 (a 被修改)

指针类型意味着多个变量指向同一块内存,因此修改一个会影响另一个。

✅ 三、内存示意图(最直观)

✔ 值类型

a (10)
b (10)  ← 拷贝出的新数据

✔ 指针类型

a (10)
b (&a) → 指向 a 的内存地址

✅ 四、函数传参时的区别(非常重要)

值类型:传值,拷贝一份

func add(x int) {
    x++
}
a := 10
add(a)
fmt.Println(a) // 10(没有改变)

指针类型:传地址,修改原变量

func add(x *int) {
    (*x)++
}
a := 10
add(&a)
fmt.Println(a) // 11(被改变了)

✅ 五、结构体特别重要:值类型默认复制!

type User struct {
    Name string
}
func change(u User) {
    u.Name = "Tom"
}
func main() {
    user := User{Name: "Sam"}
    change(user)
    fmt.Println(user.Name) // Sam(没变)
}

改用指针就会改变原数据:

func change(u *User) {
    u.Name = "Tom"
}
change(&user)
fmt.Println(user.Name)  // Tom

✅ 六、什么时候应该使用指针?

✔ 1. 需要修改函数外的变量

修改状态、计数器、累加器等。

✔ 2. struct 较大,避免复制(性能)

Go 的结构体可能很大,复制成本高:

func process(u *LargeStruct) { ... }

✔ 3. 实现方法的“接收者”为指针(避免复制)

很多类型的方法必须用指针接收器:

func (u *User) SetName(name string) {
    u.Name = name
}

✔ 4. 需要表示 nil(值不存在)

var p *User = nil

值类型永远不能为 nil。

✅ 七、一句话总结

  • 值类型保存真实值,赋值会复制,不会影响彼此。
  • 指针类型保存地址,赋值只复制地址,多个变量共享底层数据。
  • 指针多用于需要改变原数据、避免拷贝大结构体、或表示 nil 的场景。

到此这篇关于Go 语言中的值类型和指针类型的文章就介绍到这了,更多相关go语言值类型和指针类型内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • go语言中字符串嵌套的几种实现方式

    go语言中字符串嵌套的几种实现方式

    在Go语言中,字符串嵌套可以通过多种方式实现,包括使用双引号和转义字符、反引号、字符串拼接和格式化字符串,下面就来介绍一下,感兴趣的可以了解一下
    2025-03-03
  • 一文带你了解Golang中select的实现原理

    一文带你了解Golang中select的实现原理

    select是go提供的一种跟并发相关的语法,非常有用。本文将介绍 Go 语言中的 select 的实现原理,包括 select 的结构和常见问题、编译期间的多种优化以及运行时的执行过程
    2023-02-02
  • Goland激活码破解永久版及安装详细教程(亲测可以)

    Goland激活码破解永久版及安装详细教程(亲测可以)

    这篇文章主要介绍了Goland激活码破解永久版及安装详细教程(亲测可以),本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • golang DNS服务器的简单实现操作

    golang DNS服务器的简单实现操作

    这篇文章主要介绍了golang DNS服务器的简单实现操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • Golang urfave/cli库简单应用示例详解

    Golang urfave/cli库简单应用示例详解

    这篇文章主要为大家介绍了Golang urfave/cli库简单应用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 深入Golang的接口interface

    深入Golang的接口interface

    这篇文章主要介绍了深入Golang的接口interface,go不要求类型显示地声明实现了哪个接口,只要实现了相关的方法即可,编译器就能检测到,接下来关于接口interface的相关介绍需要的朋友可以参考下面文章内容
    2022-06-06
  • Go Sentinel 动态数据源配置指南(示例详解)

    Go Sentinel 动态数据源配置指南(示例详解)

    本文介绍了如何使用Go语言配置Sentinel的动态数据源,并通过本地文件和Nacos两种方式实现动态配置,通过这种方式,可以灵活地管理和更新限流规则,提升系统的稳定性和响应速度,感兴趣的朋友跟随小编一起看看吧
    2025-01-01
  • vscode中安装Go插件和配置Go环境详细步骤

    vscode中安装Go插件和配置Go环境详细步骤

    要在VSCode中配置Go语言插件,首先需要确保你的电脑已经安装了Go环境和最新版本的VSCode,这篇文章主要给大家介绍了关于vscode中安装Go插件和配置Go环境的相关资料,需要的朋友可以参考下
    2024-01-01
  • Go defer与time.sleep的使用与区别

    Go defer与time.sleep的使用与区别

    本文主要介绍了Go defer与time.sleep的使用与区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-04-04
  • 使用Go语言编译Linux平台可执行文件的完整指南

    使用Go语言编译Linux平台可执行文件的完整指南

    在Go语言开发中,跨平台编译是一个非常重要的功能,本文将详细介绍如何使用Go语言将项目编译为Linux平台的可执行文件,特别是针对国内开发者的优化配置,需要的朋友可以参考下
    2025-08-08

最新评论