hkB*_*Bst 5 rust borrow-checker
该split_at_mut函数(用于在索引处拆分可变切片)需要实现不安全的代码(根据 Rust 书)。但书中也说:“借用切片的不同部分从根本上是可以的,因为两个切片不重叠”。
我的问题:为什么借用检查器不明白借用切片的不同部分从根本上是可以的?(是否有原因阻止借用检查器理解此规则,或者只是由于某种原因尚未实施?)
使用 Rust 1.48 尝试建议的代码仍然会导致书中显示的错误:
fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
let len = slice.len();
assert!(mid <= len);
(&mut slice[..mid], &mut slice[mid..])
}
fn main() {
let mut vector = vec![1, 2, 3, 4, 5, 6];
let (left, right) = split_at_mut(&mut vector, 3);
println!("{:?}, {:?}", left, right);
}
Run Code Online (Sandbox Code Playgroud)
给出错误信息:
error[E0499]: cannot borrow `*slice` as mutable more than once at a time
--> src/main.rs:6:30
|
1 | fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
| - let's call the lifetime of this reference `'1`
...
6 | (&mut slice[..mid], &mut slice[mid..])
| -------------------------^^^^^--------
| | | |
| | | second mutable borrow occurs here
| | first mutable borrow occurs here
| returning this value requires that `*slice` is borrowed for `'1`
Run Code Online (Sandbox Code Playgroud)
为什么借用检查器不明白借用切片的不同部分从根本上是可以的?
因为一般情况下是做不到的。当然,在这种情况下,很明显&slice[..mid]和&slice[mid..]是不相交的,但是一旦你摆脱了琐碎的情况,复杂性就会飙升,很快就变得不可能了。
这些特殊的琐碎情况没有特别实施,因为:
split_at及其可变对应物来完成Indextrait 的任何东西,这意味着这(&slice[..mid], &slice[mid..])将是有效的,但(&vec[..mid], &vec[mid..])不会,这更加不一致。当然,这可以通过使Vec语言内在化来解决,但是VecDeque用户定义的数据结构呢?它只会导致太多的不一致,进而导致更多的不一致,这是 Rust 想要避免的。Rust\xe2\x80\x99s 借用检查器无法\xe2\x80\x99 理解你\xe2\x80\x99 正在借用切片的不同部分;它只知道你\xe2\x80\x99从同一个切片借用了两次。如果两个切片重叠怎么办?没有办法承认他们不是。(如果有的话,还没有实现)
\n这就是不安全存在的原因:当您确定您的代码不可能产生意外行为时,尽管编译器无法授予该行为。
\n| 归档时间: |
|
| 查看次数: |
200 次 |
| 最近记录: |