golang中具有 “no copy“的类型

在 Go 语言中,某些类型由于特殊用途或底层实现,可能会被标记为 "no copy",即它们不能被复制,通常是因为复制会导致意外的行为或错误。这些类型主要包括:


1. sync.Mutexsync.RWMutex

  • 原因:Mutex 是用于同步的锁,复制后可能会导致多个实例操作同一个底层锁的情况,从而引发竞争条件或死锁。

  • 示例

    go 复制代码
    var mu sync.Mutex
    copyMu := mu // ❌ 错误,拷贝 Mutex 会导致不可预测行为

2. sync.Cond

  • 原因sync.Cond 依赖于 sync.Mutex,如果复制,会导致多个 Cond 变量竞争同一个锁。

  • 示例

    go 复制代码
    var cond = sync.NewCond(&sync.Mutex{})
    copyCond := *cond // ❌ 不应该复制

3. sync.Once

  • 原因sync.Once 用于确保某段代码只执行一次,复制 Once 可能导致相同的初始化逻辑执行多次。

  • 示例

    go 复制代码
    var once sync.Once
    copyOnce := once // ❌ 拷贝可能会导致 `Do` 不能正确保证只执行一次

4. sync.WaitGroup

  • 原因sync.WaitGroup 维护一个内部计数器,拷贝后多个 WaitGroup 可能操作同一个计数器,导致错误。

  • 示例

    go 复制代码
    var wg sync.WaitGroup
    copyWg := wg // ❌ 复制 WaitGroup 可能导致等待逻辑混乱

5. sync.Pool

  • 原因sync.Pool 是一个对象池,拷贝会导致多个 Pool 可能共享相同的对象存储区,破坏内存管理。

  • 示例

    go 复制代码
    var pool sync.Pool
    copyPool := pool // ❌ 复制可能导致多个 Pool 共享底层存储,导致数据混乱

6. context.Context(通常不应该被复制)

  • 原因context.Context 用于控制超时、取消等,复制 Context 可能会导致取消信号不生效。

  • 示例

    go 复制代码
    ctx := context.Background()
    copyCtx := ctx // ❌ 复制 context 可能导致错误的取消行为

7. runtime/internal/atomic.NoCopy 结构体的类型

  • Go 内部提供了 runtime/internal/atomic.NoCopy 结构体,嵌入该类型的结构体会在 go vet 检查时报错,防止误复制。

  • 示例

    go 复制代码
    type myStruct struct {
        noCopy runtime/internal/atomic.NoCopy
    }

如何防止结构体被拷贝?

如果你定义的结构体不希望被复制,可以嵌入 sync.NoCopy(Go 1.20 之后正式提供):

go 复制代码
import "sync"

type MyStruct struct {
    noCopy sync.NoCopy
}

这样,go vet 工具会在发现 MyStruct 被复制时发出警告。


总结

在 Go 语言中,以下类型通常不能被复制:

  • 同步相关
    • sync.Mutex
    • sync.RWMutex
    • sync.Cond
    • sync.Once
    • sync.WaitGroup
    • sync.Pool
  • 上下文管理
    • context.Context
  • 使用 sync.NoCopyruntime/internal/atomic.NoCopy 防止拷贝的结构体

一般来说,如果一个类型涉及 锁、并发同步、状态管理 ,就要特别注意 避免拷贝,否则可能会导致竞态条件、锁丢失或不一致行为。

相关推荐
晨米酱31 分钟前
四、Prettier 编辑器集成指南
前端·代码规范
文心快码BaiduComate36 分钟前
Comate 4.0新年全面焕新!底层重构、七大升级、复杂任务驾驭力跃升
前端·程序员·架构
怪可爱的地球人1 小时前
uni-app:5 步接入 vite-plugin-uni-pages,用 <route> 自动生成 pages.json
前端
前端Hardy1 小时前
告别 !important:现代 CSS 层叠控制指南,90% 的样式冲突其实不用它也能解
前端·vue.js·面试
前端Hardy1 小时前
Vue 3 性能优化的 5 个隐藏技巧,第 4 个连老手都未必知道
前端·vue.js·面试
炫饭第一名1 小时前
速通Canvas指北🦮——路径与形状篇
前端·javascript·程序员
DeathGhost1 小时前
CSS container容器查询
前端·css
JarvanMo1 小时前
Flutter:展示大段格式化文本的挑战
前端
兆子龙1 小时前
Node.js ESM Loader Hooks 介绍:用 module.register 做转译、Import Map 与自定义解析
前端
四眼肥鱼1 小时前
flutter 利用flutter_libserialport 实现SQ800 串口通信
前端·flutter