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

Rust中对象可变引用与成员可变引用的冲突疑问

问题解答:Rust子对象可变引用的借用规则差异

这是Rust的非 lexical lifetimes(NLL,非词法生命周期)机制在起作用,核心是看引用的活跃范围(最后一次被使用的位置),而不是变量是否被"使用过"。

第一个可编译示例的原因

#[derive(Debug)]
struct Value {
    value: i32,
}

#[derive(Debug)]
struct Container {
    value: Value,
    value2: i32,
}

fn main() {
    let mut obj1 = Container { value: Value { value: 12 }, value2: 1 };

    let mut_ref1 = &mut obj1;       
    let mut_ref2 = &mut obj1.value; 
    
    mut_ref2.value = 1; 
}

你创建mut_ref1后,紧接着就创建了mut_ref2,但**mut_ref1在mut_ref2创建之后再也没有被使用过**。NLL会自动推断mut_ref1的活跃范围到mut_ref2创建前就结束了——相当于mut_ref1在你拿到mut_ref2的时候就已经"失效"了,两个可变引用的活跃范围没有重叠,自然不会违反Rust的可变引用规则。

第二个不可编译示例的原因

#[derive(Debug)]
struct Value {
    value: i32,
}

#[derive(Debug)]
struct Container {
    value: Value,
    value2: i32,
}

fn main() {
    let mut obj1 = Container { value: Value { value: 12 }, value2: 1 };

    let mut_ref1 = &mut obj1;       
    let mut_ref2 = &mut obj1.value;

    mut_ref1.value2 = 111;
}

这里你最后使用的是mut_ref1,这意味着mut_ref1的活跃范围一直持续到赋值语句mut_ref1.value2 = 111。而mut_ref2是对obj1.value的可变引用,mut_ref1作为整个obj1的可变引用,理论上可以修改obj1的所有字段(包括value),这就导致两个可变引用的活跃范围重叠了——Rust的借用检查器会认为这可能引发数据竞争,所以直接报错。

关键总结

Rust的可变引用规则不是"只要创建了多个可变引用就报错",而是同一时间内不能有重叠的可变引用。NLL会根据引用的最后使用位置来缩小活跃范围,避免不必要的报错,但如果两个可变引用的活跃范围确实重叠(比如第二个例子中mut_ref1还在被使用时,mut_ref2还活着),就会触发规则限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 09:22:42