理解 Go 语言中的值类型与引用类型

1、引用类型与值类型的区别

  • 值类型:存储数据的值。

  • 引用类型:存储数据的内存地址。

 1.1、值类型

值类型主要包含:

  • 基本数据类型(如 intfloatboolstringstruct 等)

1.2、引用类型

引用类型包括:

  • 切片(slices)

  • Map映射(maps)

  • 通道(channels)

  • 接口(interfaces)

  • 函数(functions)

2、初始化差异

2.1、new

        通常使用 new 去初始化值类型( intfloatboolstringstruct )并返回指向类型零值的指针。

package main

import (
    "fmt"
)

type Person struct {
    Name string
    Age  int
}

func main() {
    // 使用 new 创建一个 int 类型的指针
    numPtr := new(int)
    *numPtr = 42
    fmt.Println(*numPtr) // 输出: 42

    // 使用 new 创建一个 Person 类型的指针
    pPtr := new(Person)
    pPtr.Name = "Alice"
    pPtr.Age = 30
    fmt.Println(*pPtr) // 输出: {Alice 30}
}

        虽然也可以使用 new 初始化引用类型,但只会为其分配内存并返回指针,不会初始化底层数组,因此返回的值不能直接使用,通常不建议使用new初始化。

p := new([]int)
fmt.Println(*p == nil)  // 输出 true
(*p)[0] = 1  // 运行时错误:panic: runtime error: index out of range

2.2、make

        因为引用类型的复杂的内部结构,通常使用 make 去初始化引用类型,make 不仅会为其分配内存,还会对底层结构进行初始化,并返回一个已经初始化的数据结构本身。

slice := make([]int, 5)// 创建一个长度为 5 的整型切片

myMap := make(map[string]int)// 创建一个map映射数组

ch := make(chan int)// 创建一个通道

3、开发中的内存申请优化

预分配容量:在数组长度可预知的情况下,尽量指定初始容量以减少动态扩容的开销。

// 预分配长度为 0,容量为 100 的 slice
s := make([]int, 0, 100) 

// 预分配容量为 100 的 map
m := make(map[string]int, 100)

避免在循环中重复调用 make 或 new:这样会造成 GC(垃圾回收)的压力,尽量复用内存。

//原型:

package main

import (
	"fmt"
)

type Data struct {
	Value int
}

func main() {
	// 分配内存
	data := new(Data)

	for i := 0; i < 10; i++ {
		data.Value = i // 修改值

		// 处理数据
		fmt.Println(data.Value)
	}
}

4、总结

  • 引用类型 和 值类型 的主要区别在于它们存储数据的方式。

  • 使用 make 初始化引用类型时,会分配内存并初始化底层数据结构。

  • 使用 new 初始化值类型时,仅分配内存并返回指针,不会初始化底层数据结构。

  • 在开发中,合理预分配容量和避免重复内存分配可以有效减少 GC 压力,提升程序性能。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值