导读:本期聚焦于小伙伴创作的《Go语言中切片预分配与填充指针类型和值类型的最佳实践是什么》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Go语言中切片预分配与填充指针类型和值类型的最佳实践是什么》有用,将其分享出去将是对创作者最好的鼓励。

在Go语言编程中,切片是使用频率极高的数据结构,合理的预分配和填充策略能显著降低内存分配次数,提升程序运行效率,而指针类型和值类型的切片在操作时存在不同的注意事项。

Go语言中切片预分配与填充指针类型和值类型的最佳实践是什么

切片预分配的基本原理

Go语言中切片的底层是数组,当使用append函数向切片添加元素时,如果底层数组容量不足,会触发扩容操作,扩容会申请新的更大的数组并将原有元素拷贝过去,带来额外的性能开销。预分配就是通过make函数提前指定切片的容量,减少扩容次数。

预分配切片的基本语法为:

// 声明长度为0,容量为n的切片
slice := make([]Type, 0, n)
// 声明长度为n,容量为n的切片
slice := make([]Type, n)

值类型切片的最佳实践

预分配策略

对于值类型切片,比如[]int[]struct等,如果需要逐个填充元素,建议使用make([]Type, 0, n)的方式预分配容量,然后通过append添加元素,这样既能保证容量足够,又不会提前初始化元素占用不必要的内存。

如果需要提前初始化所有元素,可以使用make([]Type, n),此时切片的长度为n,每个元素会被初始化为对应值类型的零值,之后可以直接通过索引赋值。

填充方式示例

以下是一个值类型切片的预分配和填充示例:

package main

import "fmt"

type Point struct {
	X int
	Y int
}

func main() {
	// 预分配容量为5的值类型切片
	points := make([]Point, 0, 5)
	// 通过append填充元素
	points = append(points, Point{X: 1, Y: 2})
	points = append(points, Point{X: 3, Y: 4})
	fmt.Println(points)

	// 预分配长度和容量均为5的切片,直接索引赋值
	points2 := make([]Point, 5)
	points2[0] = Point{X: 1, Y: 2}
	points2[1] = Point{X: 3, Y: 4}
	fmt.Println(points2)
}

注意事项

值类型切片的元素是直接存储在切片底层数组中的,修改切片中的元素不会影响其他变量,但是如果切片被传递给其他函数,传递的是底层数组的拷贝引用,修改元素会影响原切片的内容。

指针类型切片的最佳实践

预分配策略

指针类型切片比如[]*Point,预分配时同样优先使用make([]*Type, 0, n)的方式减少扩容,由于指针类型的零值是nil,如果预分配长度为n,每个元素初始都是nil,需要额外为指针指向的结构体分配内存。

填充方式示例

指针类型切片的填充需要先为指针指向的对象分配内存,再将指针放入切片:

package main

import "fmt"

type Point struct {
	X int
	Y int
}

func main() {
	// 预分配容量为5的指针类型切片
	pointPtrs := make([]*Point, 0, 5)
	// 为结构体分配内存,将指针添加到切片
	p1 := &Point{X: 1, Y: 2}
	pointPtrs = append(pointPtrs, p1)
	p2 := &Point{X: 3, Y: 4}
	pointPtrs = append(pointPtrs, p2)
	fmt.Println(pointPtrs)

	// 预分配长度和容量均为5的指针切片,逐个初始化指针
	pointPtrs2 := make([]*Point, 5)
	pointPtrs2[0] = &Point{X: 1, Y: 2}
	pointPtrs2[1] = &Point{X: 3, Y: 4}
	fmt.Println(pointPtrs2)
}

注意事项

指针类型切片的元素存储的是指针,多个切片元素可以指向同一个结构体实例,修改实例内容会影响所有指向该实例的指针。如果预分配时使用make([]*Type, n),不要忘记为每个非nil的元素分配实际的结构体内存,避免出现空指针解引用错误。

两种类型的选择建议

如果切片元素较小,且不需要共享元素实例,优先选择值类型切片,预分配时使用make([]Type, 0, n)配合append填充即可,性能更优且更不容易出现空指针问题。

如果切片元素较大,或者需要多个切片元素共享同一个实例,或者需要表示元素可能不存在的场景,选择指针类型切片,预分配时同样优先指定容量,填充时确保为每个指针分配有效的内存地址。

以下是两种切片的预分配和填充对比:

对比项 值类型切片 指针类型切片
预分配语法 make([]Type, 0, n) make([]*Type, 0, n)
元素存储内容 实际元素值 指向元素的指针
填充前提 无需额外分配内存 需为指针指向的对象分配内存
适用场景 元素小、无需共享实例 元素大、需要共享实例、表示可选元素

Go_slice指针类型值类型预分配切片填充修改时间:2026-06-05 22:02:03

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。