为何Rust允许通过不可变绑定的可变引用字段修改对象?
Great question! This cuts to the core of Rust’s nuanced approach to mutability—let’s unpack why this behavior is allowed, why it doesn’t break Rust’s rules, and how it differs from immutable references.
First, clarify Rust’s mutability basics
Rust’s "immutability" rule isn’t about making objects permanently unchangeable—it’s about binding immutability and reference permissions:
- An immutable binding (
let x = ...) means you can’t reassign the binding itself, or modify the direct fields of the value it points to (if that value is a struct/enum). - A mutable reference (
&mut T) grants permission to modify the object it points to—this permission is part of the reference’s type, separate from the binding holding the reference.
Why modifying the mutable reference’s target is allowed
When you have an immutably bound struct containing a &mut T field, you’re not violating any rules because:
- You’re not modifying the struct itself: You can’t reassign the struct’s
&mut Tfield (e.g., make it point to a different object)—that would require modifying the struct, which the immutable binding forbids. - You’re using the mutable reference’s inherent permission: The
&mut Texists specifically to allow modifying its target. Since you’re not changing the reference itself (just using its granted access), this is fully compliant with Rust’s safety guarantees.
Let’s look at a concrete code example to make this tangible:
struct RefContainer { value: &mut i32, } fn main() { let mut underlying_num = 10; // Immutable binding to a struct holding a mutable reference let container = RefContainer { value: &mut underlying_num }; // ❌ Compile error: Can't modify the struct's field (the reference itself) // let mut another_num = 20; // container.value = &mut another_num; // ✅ Allowed: Use the mutable reference's permission to modify its target *container.value = 100; println!("{}", underlying_num); // Outputs 100 }
Why immutable references can’t do this
The difference with &T (immutable references) is simple: immutable references don’t grant permission to modify their target. Even if you put an immutable reference in an immutably bound struct, the reference’s type inherently blocks writes to its target—this has nothing to do with the struct’s binding, and everything to do with the reference’s own permissions.
Example with an immutable reference:
struct ImmutableRefContainer { value: &i32, } fn main() { let num = 10; let container = ImmutableRefContainer { value: &num }; // ❌ Compile error: Immutable reference doesn't allow modifying the target // *container.value = 20; }
To sum it up
This behavior doesn’t contradict Rust’s immutability rules—it’s a natural result of separating three distinct concepts:
- Binding mutability: Whether you can reassign the variable or modify its direct fields.
- Struct field mutability: Controlled by the binding and struct definition.
- Reference permission: Whether the reference allows reading/writing its target.
When you use a mutable reference inside an immutably bound struct, you’re only exercising the permission granted by the reference itself—you’re not modifying the struct or its fields, so Rust lets it pass.
内容的提问来源于stack exchange,提问作者something_clever

