全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

如何避免 Go 中字节切片(byte slice)在函数调用中被意外修改

go 中切片是引用类型,直接赋值不会复制底层数组;若需保持原切片不变,必须显式创建独立副本(如用 append([]byte(nil), src...)),否则 shuffle 等就地操作会同时影响原始数据。

在 Go 语言中,[]byte 是一个切片(slice),其底层结构包含指向数组的指针、长度(len)和容量(cap)。当你执行 cryptkey := alphabet 时,并未创建新底层数组,而是让 cryptkey 和 alphabet 共享同一块内存。因此,后续对 cryptkey 的任何就地修改(如交换元素)都会直接反映在 alphabet 上——这正是你观察到“两个切片都被打乱”的根本原因。

要真正隔离数据,必须进行深拷贝(deep copy)。最简洁、惯用且安全的方式是使用 append 构造新切片:

out := append([]byte(nil), b...)

该语句等价于:分配一个长度为 len(b)、类型为 []byte 的新切片,并将 b 的所有元素逐个复制进去。[]byte(nil) 提供空切片作为起点,append 自动处理内存分配,语义清晰且零分配冗余(相比 make([]byte, len(b)) + copy() 更简练)。

修正后的完整示例:

package main

import (
    "fmt"
    "math/rand"
    "time" // 注意:添加 time 包以正确初始化随机种子
)

func main() {
    alphabet := []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz.")
    cryptkey := alphabet // 此时仍共享底层数组(但后续 shuffle 不再影响它)

    fmt.Println("Original alphabet:", string(alphabet))

    // 初始化随机种子,避免每次运行结果相同
    rand.Seed(time.Now().UnixNano())
    cryptkey = shuffle(cryptkey)

    fmt.Println("After shuffle — alphabet unchanged:", string(alphabet))
    fmt.Println("Shuffled cryptkey:", string(cryptkey))
}

func shuffle(b []byte) []byte {
    l := len(b)
    if l <= 1 {
        return append([]byte(nil), b...) // 边界情况也保证副本
    }
    out := append([]byte(nil), b...) // ✅ 关键:创建独立副本

    for i := range out {
        dest := rand.Intn(l)
        out[i], out[dest] = out[dest], out[i]
    }
    return out
}

⚠️ 注意事项

  • rand.Intn 在 Go 1.20+ 已弃用,生产环境建议改用 rand.New(rand.NewSource(seed)).Intn(l) 或 rand.New(rand.NewPCG()),但本例为简洁保留旧用法(需配合 rand.Seed);
  • 切勿使用 out := b[:len(b):len(b)] 或 out := b,它们仍共享底层数组;
  • 若需高性能批量复制,copy(dst, src) 亦可,但 append(..., b...) 更符合 Go 的惯用风格且不易出错。

总结:Go 中切片赋值不等于复制数据。凡涉及可能修改切片内容的函数(如 shuffle、reverse、sort.Slice 等),务必在函数内部通过 append([]T(nil), s...) 或 copy 显式创建副本,才能保障输入参数的不可变性(immutability)与函数纯度(purity)。


# go  # app  # 字节  # ai  # unix  # sort  # 指针  # 引用类型  # 切片  # len  # cap  # nil  # append  # copy  # 是一个  # 若需  # 当你  # 并将  # 高性能  # 亦可  # 不等于  # 根本原因  # 如用  # 更符合 


相关文章: SQL查询语句优化的实用方法总结  制作网站的基本流程,设计网站的软件是什么?  实例解析angularjs的filter过滤器  建站之星安装后界面空白如何解决?  免费视频制作网站,更新又快又好的免费电影网站?  网站微信制作软件,如何制作微信链接?  高端智能建站公司优选:品牌定制与SEO优化一站式服务  宝塔面板创建网站无法访问?如何快速排查修复?  电视网站制作tvbox接口,云海电视怎样自定义添加电视源?  如何通过智能用户系统一键生成高效建站方案?  如何在Golang中处理模块冲突_解决依赖版本不兼容问题  黑客如何通过漏洞一步步攻陷网站服务器?  如何在阿里云虚拟主机上快速搭建个人网站?  建站之星备案是否影响网站上线时间?  如何在腾讯云服务器上快速搭建个人网站?  建站之星如何防范黑客攻击与数据泄露?  宝塔建站无法访问?如何排查配置与端口问题?  名字制作网站免费,所有小说网站的名字?  建站主机选购指南与交易推荐:核心配置解析  零服务器AI建站解决方案:快速部署与云端平台低成本实践  Swift中循环语句中的转移语句 break 和 continue  已有域名如何免费搭建网站?  微信网站制作公司有哪些,民生银行办理公司开户怎么在微信网页上查询进度?  建站之星CMS五站合一模板配置与SEO优化指南  上海制作企业网站有哪些,上海有哪些网站可以让企业免费发布招聘信息?  网站制作需要会哪些技术,建立一个网站要花费多少?  建站之星如何配置系统实现高效建站?  宝华建站服务条款解析:五站合一功能与SEO优化设置指南  交易网站制作流程,我想开通一个网站,注册一个交易网址,需要那些手续?  网站制作新手教程,新手建设一个网站需要注意些什么?  武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?  在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?  PHP正则匹配日期和时间(时间戳转换)的实例代码  视频网站app制作软件,有什么好的视频聊天网站或者软件?  建站之星×万网:智能建站系统+自助建站平台一键生成  建站org新手必看:2024最新搭建流程与模板选择技巧  杭州银行网站设计制作流程,杭州银行怎么开通认证方式?  想学网站制作怎么学,建立一个网站要花费多少?  武汉外贸网站制作公司,现在武汉外贸前景怎么样啊?  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  建站主机默认首页配置指南:核心功能与访问路径优化  c# 在ASP.NET Core中管理和取消后台任务  建站之星Pro快速搭建教程:模板选择与功能配置指南  文字头像制作网站推荐软件,醒图能自动配文字吗?  建站之星如何助力企业快速打造五合一网站?  javascript中对象的定义、使用以及对象和原型链操作小结  如何自定义建站之星模板颜色并下载新样式?  ,巨量百应是干嘛的?  北京网页设计制作网站有哪些,继续教育自动播放怎么设置?  建站之星CMS建站配置指南:模板选择与SEO优化技巧 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。