[Rust笔记] 研究变量生存期, 记录下 NLL 的一些反直觉行为

本文深入探讨了Rust的Non-Lexical Lifetimes (NLL)特性如何影响变量的作用域和生存期。通过示例,解释了NLL如何在某些情况下延长或缩短变量的生存期,导致编译错误或符合直觉的行为。重点讨论了循环、Drop trait以及强制外部变量生存期延长的情况,展示了NLL在确保内存安全和编译时错误检查中的复杂性。
摘要由CSDN通过智能技术生成

NLL 导致的非直觉的作用域扩大

1. NLL 完全无视词法作用域

1.1. 是否可以认为 NLL 在fb.set(&b);处缩短了fb的起始生存期以配合b?
1.2. 应该认为 NLL 缩短了fb 还是延长了b 的生存期?

struct MyCell<T>(T);
impl<T> MyCell<T> {
    pub fn set(&mut self, t: T) {
        self.0 = t;
    }
}
let a = 3;
let mut fb = MyCell(&a); // 将 fb 绑定到 a 的生存期
let _ = {
    let b = 4;
    fb.set(&b);
    false
    // 直觉上 b 在此结束生存期
};
// 直觉上 fb 在此结束生存期
// NLL 智能的使 b 和 fb 的生存期同时结束, 使得 fb 可以使用 b

2. 强制延长外部变量生存期得到符合直觉的编译失败

struct MyCell<T>(T);
impl<T> MyCell<T> {
    pub fn set(&mut self, t: T) {
        self.0 = t;
    }
}
let a = 3;
let mut fb = MyCell(&a); // 将 fb 绑定到 a 的生存期
let _ = {
    let b = 4;
    fb.set(&b);
    false
    // b 在此结束生存期
};
fb; // 强制延长 fb 生存期

3. Drop导致隐式生存期延长而编译失败

主代码与 1 完全相同, 与 1 相比仅多一个空Drop, 而编译失败原因同 2

struct MyCell<T>(T);
impl<T> MyCell<T> {
    pub fn set(&mut self, t: T) {
        self.0 = t;
    }
}
impl<T> Drop for MyCell<T> {
    fn drop(&mut self) {}
}
let a = 3;
let mut fb = MyCell(&a); // 将 fb 绑定到 a 的生存期
let _ = {
    let b = 4;
    fb.set(&b);
    false
    // b 在此结束生存期
};
// drop 导致的隐式延长 fb 生存期

4. 编译失败 循环使得fb生存期不能缩短

有可能rust升级使其可通过编译

struct MyCell<T>(T);
impl<T> MyCell<T> {
    pub fn set(&mut self, t: T) {
        self.0 = t;
    }
}
let a = 3;
let mut fb = MyCell(&a); // 将 fb 绑定到 a 的生存期
let _ = loop {
    // loop 使得 fb 必须在此有效 而不能使 b 满足此要求
    let b = 4;
    fb.set(&b);
    if true { break false }
    // b 在此结束生存期
};
// fb 在此结束生存期

5. 编译成功 基本等同于 4

NLL 过于智能的消除了 loop

struct MyCell<T>(T);
impl<T> MyCell<T> {
    pub fn set(&mut self, t: T) {
        self.0 = t;
    }
}
let a = 3;
let mut fb = MyCell(&a); // 将 fb 绑定到 a 的生存期
let _ = loop {
    let b = 4;
    fb.set(&b);
    break false; // 过于智能的消除了 loop
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值