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

Written by

in

文章目录
  • 特性 值类型 指针类型 存储内容 实际数据 数据的内存地址(指向某个值) 赋值时 拷贝整份数据 拷贝地址(两个指针指向同一块内存) 改动是否影响原变量 ❌ 不影响 ✔ 会影响 空值 无法为 nil 可以为 nil 内存分配 栈为主 指向堆或栈都可能
  • 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
  • 值类型保存真实值,赋值会复制,不会影响彼此。 指针类型保存地址,赋值只复制地址,多个变量共享底层数据。 指针多用于需要改变原数据、避免拷贝大结构体、或表示 nil 的场景。 到此这篇关于Go 语言中的值类型和指针类型的文章就介绍到这了,更多相关go语言值类型和指针类型内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: go语言中值类型和指针类型的深入理解 golang中值类型/指针类型的变量区别总结 Go语言的方法接受者类型用值类型还是指针类型?
  • 目录
    • ✅ 一、值类型 vs 指针类型 — 本质区别
    • ✅ 二、本质理解:变量保存的是什么?
      • ✔ 值类型(int、float、struct、array 等)
      • ✔ 指针类型(*int、*struct、*MyType)
    • ✅ 三、内存示意图(最直观)
      • ✔ 值类型
      • ✔ 指针类型
    • ✅ 四、函数传参时的区别(非常重要)
      • 值类型:传值,拷贝一份
      • 指针类型:传地址,修改原变量
        • ✔ 1. 需要修改函数外的变量
        • ✔ 2. struct 较大,避免复制(性能)
        • ✔ 3. 实现方法的“接收者”为指针(避免复制)
        • ✔ 4. 需要表示 nil(值不存在)
    • ✅ 五、结构体特别重要:值类型默认复制!
      • ✅ 六、什么时候应该使用指针?
        • ✅ 七、一句话总结

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

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

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

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

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

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

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

          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

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

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

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

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

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

          var p *User = nil

          值类型永远不能为 nil。

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

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

          您可能感兴趣的文章:

          • go语言中值类型和指针类型的深入理解
          • golang中值类型/指针类型的变量区别总结
          • Go语言的方法接受者类型用值类型还是指针类型?

          站内搜索