tezvyn:

Rust borrow rules versus Go race prevention

AI-drafted, machine-checkedSource: interviewintermediate
WHAT IT TESTS

how each language stops data races.

OUTLINE

Rust's aliasing-XOR-mutability rule plus Send and Sync make races a compile error; Go prevents them at runtime via channels, mutexes and the race detector.

WHAT THIS TESTS Whether you understand the mechanism by which Rust makes data races impossible to compile, and how Go's model instead relies on conventions and runtime tooling.

A GOOD ANSWER COVERS A data race needs concurrent access to the same memory with at least one writer and no synchronization. Rust's borrow checker enforces that at any time you may have either one mutable reference or any number of immutable references, never both. This aliasing-XOR-mutability rule means you cannot have a writer and a reader of the same data simultaneously, so single-threaded mutation aliasing bugs vanish. The Send and Sync marker traits extend the guarantee across threads: only types safe to move or share between threads can cross, so the compiler rejects sharing a non-thread-safe value. The result is that data races are caught at compile time. Go takes a different path: its motto is to share memory by communicating, using channels to pass ownership, or sync.Mutex and sync.RWMutex to guard shared state, plus atomics. None of this is compiler-enforced, so the runtime race detector exists to catch violations during testing.

COMMON WRONG ANSWERS Saying Go's compiler prevents races. Claiming Rust never needs Mutex or Arc; it does for shared mutable state across threads, just safely typed. Confusing data races with general race conditions, which Rust does not eliminate.

LIKELY FOLLOW-UPS What do Send and Sync actually mean. How do Arc and Mutex combine for shared state in Rust. What does the Go race detector do and not do. Difference between data race and logical race condition.

ONE CONCRETE EXAMPLE Sharing a counter across threads: in Rust you wrap it in Arc<Mutex<i32>>; the type system forces you to lock before mutating, and you literally cannot compile code that mutates it from two threads without the lock. In Go you guard an int with a sync.Mutex and call Lock and Unlock around updates, but if you forget, it still compiles and may race; you would only catch it by running the race detector in tests.

Read the original → doc.rust-lang.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.