go 1.21+ 可直接使用内置的 `slices.reverse`;旧版本需手动循环、泛型函数或反射实现,所有方法均支持原地反转,如需保留原切片,应先调用 `slices.clone` 复制。
在 Go 中反转切片是一个高频操作,但标准库在不同版本中提供了差异化的支持方案。自 Go 1.21 起,slices 包(位于 golang.org/x/exp/slices 的功能已正式并入标准库 sli
ces)新增了通用、安全且高效的 Reverse 函数,适用于任意可索引切片类型(如 []int、[]string、[]struct{} 等),无需类型断言或反射开销。
✅ 推荐方式(Go ≥ 1.21):
import "slices"
s := []int{1, 2, 3, 4, 5}
slices.Reverse(s) // 原地反转 → [5 4 3 2 1]该函数是泛型实现,类型安全、零分配、性能最优,且已通过充分测试,是当前首选方案。
⚠️ 兼容旧版本(Go
手动双指针循环(最通用、无依赖、高性能):
适用于所有 Go 版本,清晰易懂,无额外开销:
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}泛型函数(Go ≥ 1.18,类型安全首选):
封装为可复用工具函数,支持任意切片类型:
func Reverse[S ~[]E, E any](s S) {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
}
// 使用示例
nums := []int{10, 20, 30}
Reverse(nums) // → [30 20 10]反射方案(Go ≥ 1.8,慎用):
可处理任意切片类型(包括未导出字段结构体切片),但性能较差、失去类型检查,仅作兜底:
import "reflect"
func ReverseAny(s interface{}) {
v := reflect.ValueOf(s)
if v.Kind() != reflect.Slice {
panic("ReverseAny: given value is not a slice")
}
n := v.Len()
swap := reflect.Swapper(s)
for i, j := 0, n-1; i < j; i, j = i+1, j-1 {
swap(i, j)
}
}? 重要注意事项:
reversed := slices.Clone(original) slices.Reverse(reversed)
总结:优先升级至 Go 1.21+ 并使用 slices.Reverse;若需兼容旧版本,推荐泛型 Reverse 函数——兼顾安全性、可读性与性能;反射方案仅在极端动态场景下考虑,并务必添加运行时类型校验。