You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言多重赋值的原子性疑问:从开发者视角解析

Go多重赋值的"原子性":从开发者视角解析

Great question! Let's unpack this clearly, since the Go spec's wording can feel a bit abstract at first.

First, let's clarify what we mean by "atomicity" here—from a developer's perspective, you're asking if operations like a, b = b, a happen as an indivisible unit, without intermediate states messing things up. The short answer is: in a single goroutine, yes, this behaves like an atomic operation for logical purposes. In concurrent scenarios without synchronization? No.

Let's break down the Go spec's two-phase assignment rule you mentioned:

The assignment proceeds in two phases. First, the operands of index expressions and pointer indirections (including implicit pointer indirections in selectors) on the left and the expressions on the right are all evaluated in the usual order. Second, the assignments are carried out in left-to-right order.

What this means in practice

  1. Phase 1: All values are calculated first
    For a, b = b, a, Go will first evaluate the right-hand side expressions: it grabs the current value of b and the current value of a, storing these temporary values somewhere. It also resolves any left-hand side expressions (like if you had s[i], s[j] = s[j], s[i], it would calculate the indices i and j first).

    Crucially, none of the left-hand variables are modified during this phase. The values used for the assignment are frozen at the start of the operation.

  2. Phase 2: Assignments happen left-to-right
    Once all values are ready, Go assigns the first temporary value (original b) to a, then the second temporary value (original a) to b.

    In a single goroutine, you'll never observe an intermediate state where a has been updated but b hasn't—because your code runs sequentially, and the assignment steps are completed before any subsequent lines execute. This is why a, b = b, a works perfectly for swapping values in your Playground tests.

The catch: Concurrent goroutines

If other goroutines are accessing a and b without synchronization (like mutexes, channels, or atomic operations), things get tricky. The left-to-right assignment in Phase 2 is not a hardware-level atomic operation. Another goroutine could potentially see a updated to the new value while b still holds the old one (or vice versa), depending on how the compiler schedules instructions.

So for concurrent access, you still need to use proper synchronization primitives—multiplexed assignment alone won't make the operation atomic in a thread-safe way.

Example to confirm

Let's say we have:

a := 1
b := 2
a, b = b, a

During Phase 1, Go captures b=2 and a=1. Then Phase 2 sets a=2, then b=1. There's no way b would end up as 2 here—because the value assigned to b was captured before a was modified.

内容的提问来源于stack exchange,提问作者Vojtech Kane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:39:19