you_can::turn_off_the_borrow_checker
摘要
介绍了一个用于教学目的的 Rust 宏,它能抑制借用检查器的错误,但警告说该宏在生产环境中不安全。
暂无内容
查看缓存全文
缓存时间: 2026/05/25 12:46
# turn_off_the_borrow_checker 在 you_can - Rust 中
来源:https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html
## 属性宏 turn\_off\_the\_borrow\_checker
来源(https://docs.rs/you-can-build-macros/0.0.14/x86_64-unknown-linux-gnu/src/you_can_build_macros/lib.rs.html#33)
``
#[turn_off_the_borrow_checker]
``
展开说明你**无法**在 Rust 中“关闭借用检查器”(https://steveklabnik.com/writing/you-can-t-turn-off-the-borrow-checker-in-rust),你也不应该想要这样做。Rust 的引用(https://doc.rust-lang.org/std/primitive.reference.html)并不是指针,编译器可以随意肢解试图将引用当作指针使用的代码。如果你需要在 Rust 中使用裸指针行为,请不要使用此宏,而是使用 Rust 的实际裸指针(https://doc.rust-lang.org/std/primitive.pointer.html),它们不会向编译器做出相同的别名保证。然而,如果你想要假装借用检查器不存在——**仅用于教育目的,绝不能用于生产代码**——这个宏可以抑制它所应用代码中的许多(但不是所有)借用检查器错误。
这不会破坏任何原本合法的代码;借用检查器不影响编译输出,只验证输入的有效性。然而,它将允许不健全且不安全的胡闹行为,这些行为会不可预测且危险地失败。这**使用起来并不安全**。
#### §(https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html#example)示例
##### §(https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html#without-macro)无宏
``
fn main() {
let mut owned = vec![1, 32];
let mut_1 = &mut owned[0];
let mut_2 = &mut owned[1];
//~^ 错误:不能同时多次借用 `owned` 为可变
drop(owned);
//~^ 错误:不能因为被借用而移出 `owned`
let undefined = *mut_1 + *mut_2;
println!("{undefined}");
}
``
##### §(https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html#with-macro)有宏
``
#[you_can::turn_off_the_borrow_checker]
fn main() {
let mut owned = vec![1, 32];
let mut_1 = &mut owned[0];
let mut_2 = &mut owned[1];
//~^ 警告:这些引用的借用检查器已被抑制。
drop(owned);
let undefined = *mut_1 + *mut_2;
println!("{undefined}");
}
``
### §(https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html#explanation)解释
该宏会查找代码中通过 `&` 或 `&mut` 运算符,或 `ref` 和 `ref mut` 绑定创建的引用,并用我们的 `borrow_unchecked()`(https://docs.rs/you-can/latest/you_can/fn.borrow_unchecked.html)函数包裹它们,以解除其生命周期(https://doc.rust-lang.org/nomicon/unbounded-lifetimes.html),从而使借用检查器有效地忽略它们。如果在 nightly 版本上运行,它还会为每个被修改的引用添加新的警告诊断信息。
##### §(https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html#expanded)展开后
``
fn main() {
let mut owned = vec![1, 32];
let mut_1 = unsafe { ::you_can::borrow_unchecked(&mut owned[0]) };
let mut_2 = unsafe { ::you_can::borrow_unchecked(&mut owned[1]) };
drop(owned);
let undefined = *mut_1 + *mut_2;
println!("{undefined}");
}
``
这种方法存在局限性。它无法抑制因代码非法组合其他地方创建的生命周期,或隐式创建的引用而导致的错误。作为一种解决办法,有时可以在需要显式引用的地方加上 `&*` 前缀来强制创建显式引用,如下例所示。
#### §(https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html#example-1)示例
``
#[you_can::turn_off_the_borrow_checker]
fn main() {
let mut source = Some(1);
let inner_mut = &*source.as_ref().unwrap();
let mutable_alias = &mut source;
source = None;
*mutable_alias = Some(2);
if let Some(ref mut inner_a) = source {
match source {
Some(ref mut inner_b) => {
*inner_b = inner_mut + 1;
*inner_a = inner_mut + 2;
},
None => {
println!("none");
},
}
}
println!("{source:?}");
}
``
##### §(https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html#expanded-1)展开后
``
fn main() {
let mut source = Some(1);
let inner_mut = unsafe { ::you_can::borrow_unchecked(&*source.as_ref().unwrap()) };
let mutable_alias = unsafe { ::you_can::borrow_unchecked(&mut source) };
source = None;
*mutable_alias = Some(2);
if let Some(ref mut inner_a) = source {
let inner_a = unsafe { ::you_can::borrow_unchecked(inner_a) };
match source {
Some(ref mut inner_b) => {
let inner_b = unsafe { ::you_can::borrow_unchecked(inner_b) };
*inner_b = inner_mut + 1;
*inner_a = inner_mut + 2;
},
None => {
println!("none");
},
}
}
println!("{source:?}");
}
``
### §(https://docs.rs/you-can/latest/you_can/attr.turn_off_the_borrow_checker.html#discussions)相关讨论
以下是一些相关讨论,主要讨论为什么你不应该这样做:
- https://reddit.com/s9az4y
- https://internals.rust-lang.org/t/16001
- https://news.ycombinator.com/item?id=30031323
- https://twitter.com/pcwalton/status/1485718602233704452
- https://smitop.com/post/rust-skip-borrowck
相似文章
无类型检查的生命周期借用检查
一篇博客文章介绍了一种玩具语言,它在运行时而非静态类型系统中强制执行借用检查,通过在栈上使用轻量级引用计数来支持内部指针和单一所有权,适用于动态类型环境。
在 nightly 上启用下一代借用检查器
Rust 博客宣布在 nightly 构建中启用下一代借用检查器 Polonius Alpha,带来流敏感的借用检查,并为今年晚些时候的稳定化铺平道路。
An alias-based formulation of the borrow checker (2018)
Niko Matsakis describes an alternative alias-based formulation of Rust's borrow checker, where regions are sets of loans rather than program points, with a working prototype that passes the NLL test suite.
BorrowSanitizer
BorrowSanitizer 是一个开源的 LLVM sanitizer,用于检测多语言应用程序中 Rust 特有的别名违规,旨在足够快以支持模糊测试,并支持 Rust、C 和 C++ 互操作。
Rust 中的进行中工作
本文介绍了一种在 Rust 开发过程中延迟错误处理的技术和库,允许开发者临时将错误降级为警告,从而在保持正确性的同时维持生产力。