我有一个持久的编译错误,其中Rust抱怨我在尝试可变借用时有一个不可变的借位,但是不可变借用来自另一个范围,而我并没有从中带来任何东西.
我有一些代码检查地图中的值,如果它存在,则返回它,否则它需要以各种方式改变地图.问题是我似乎无法找到让Rust同时执行的方法,即使这两个操作完全分开.
这是一些荒谬的代码,它遵循与我的代码相同的结构并展示了问题:
use std::collections::BTreeMap;
fn do_stuff(map: &mut BTreeMap<i32, i32>, key: i32) -> Option<&i32> {
// extra scope in vain attempt to contain the borrow
{
// borrow immutably
if let Some(key) = map.get(&key) {
return Some(key);
}
}
// now I'm DONE with the immutable borrow, but rustc still thinks it's borrowed
map.insert(0, 0); // borrow mutably, which errors
None
}
Run Code Online (Sandbox Code Playgroud)
这出错了:
error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
--> src/lib.rs:14:5
|
3 …Run Code Online (Sandbox Code Playgroud) 前几天,有一个问题,如果有人有一个问题,一个可变引用其中包含借来的数据本身就是一种类型的连接寿命.问题是提供对类型的引用,借用与类型内部借用数据相同的生命周期.我试图重新创建问题:
struct VecRef<'a>(&'a Vec<u8>);
struct VecRefRef<'a>(&'a mut VecRef<'a>);
fn main() {
let v = vec![8u8, 9, 10];
let mut ref_v = VecRef(&v);
create(&mut ref_v);
}
fn create<'b, 'a>(r: &'b mut VecRef<'a>) {
VecRefRef(r);
}
Run Code Online (Sandbox Code Playgroud)
我'b在这里明确注释了create().这不编译:
error[E0623]: lifetime mismatch
--> src/main.rs:12:15
|
11 | fn create<'b, 'a>(r: &'b mut VecRef<'a>) {
| ------------------
| |
| these two types are declared with different lifetimes...
12 | VecRefRef(r);
| ^ ...but data from `r` flows …Run Code Online (Sandbox Code Playgroud) 为什么编译器拒绝此代码:
struct S<'a> {
i: i32,
r: &'a i32,
}
fn main() {
let mut s = S{i: 0, r: &0};
{
let m1 = &mut s;
m1.r = &m1.i;
}
let m2 = &mut s;
}
Run Code Online (Sandbox Code Playgroud)
错误是:"不能s一次多次借用可变的"(首先借用:m1,第二次借用:) m2.
超出范围s后m1,为什么第一次借用还活着?
我读到了超出原借款人范围的借款范围扩展.然而,这似乎总是涉及原始借款人范围之外的另一个借款人"接管"原始借款,例如,此代码失败并出现完全相同的错误,这对我来说很清楚:
fn main() {
let mut s = 0;
let r: &mut i32;
{
let m1 = &mut s;
r = m1;
}
let m2 = &mut s;
}
Run Code Online (Sandbox Code Playgroud)
在第一个例子中,如果我替换m1.r …
我无法理解为什么在借款人的范围结束后仍然借用可变借入变量.看起来它与特质使用有关,但我不明白为什么:
fn main() {
let mut a = 10;
test::<FooS>(&mut a);
println!("out {:?}", a)
}
trait Foo<'a> {
fn new(data: &'a mut u32) -> Self;
fn apply(&mut self);
}
struct FooS<'a> {
data: &'a mut u32,
}
impl<'a> Foo<'a> for FooS<'a> {
fn new(data: &'a mut u32) -> Self {
FooS { data: data }
}
fn apply(&mut self) {
*self.data += 10;
}
}
fn test<'a, F>(data: &'a mut u32)
where F: Foo<'a>
{
{
// let mut foo …Run Code Online (Sandbox Code Playgroud) 我正在尝试在Rust中实现Chain of Responsibility设计模式:
pub trait Policeman<'a> {
fn set_next(&'a mut self, next: &'a Policeman<'a>);
}
pub struct Officer<'a> {
deduction: u8,
next: Option<&'a Policeman<'a>>,
}
impl<'a> Officer<'a> {
pub fn new(deduction: u8) -> Officer<'a> {
Officer {deduction, next: None}
}
}
impl<'a> Policeman<'a> for Officer<'a> {
fn set_next(&'a mut self, next: &'a Policeman<'a>) {
self.next = Some(next);
}
}
fn main() {
let vincent = Officer::new(8); // -+ vincent enters the scope
let mut john = Officer::new(5); // -+ john …Run Code Online (Sandbox Code Playgroud) tl;dr given pub fn func(&'a mut self),为什么在运行后被self认为是“可变借用的” ? func
鉴于以下最小可行示例(操场)
pub struct Struct1<'a> {
var: &'a u8,
}
impl<'a> Struct1<'a> {
pub fn new() -> Struct1<'a> {
return Struct1 {
var: &33,
}
}
pub fn func(&'a mut self) -> () {
()
}
}
fn main() {
let mut s1 = Struct1::new();
s1.func(); // point 1
// point 2
s1.func(); // point 3
}
Run Code Online (Sandbox Code Playgroud)
导致编译器错误
error[E0499]: cannot borrow `s1` as mutable …Run Code Online (Sandbox Code Playgroud) 游戏的最小示例,玩家拥有一个位置并随着时间的流逝而走动。编译如下:
use std::thread::sleep;
use std::time::Duration;
struct Player {
position: usize,
}
impl Player {
fn new() -> Self {
Self { position: 0 }
}
}
impl Player {
fn get_position(&self) -> usize {
self.position
}
}
impl Player {
fn walk(&mut self) {
self.position += 1;
}
}
fn main() {
let mut player = Player::new();
loop {
player.walk();
sleep(Duration::from_secs(1));
}
}
Run Code Online (Sandbox Code Playgroud)
如果玩家借用该位置而不是拥有它,则不会编译:
use std::thread::sleep;
use std::time::Duration;
struct Player<'a> {
position: &'a mut usize,
}
impl<'a> Player<'a> {
fn …Run Code Online (Sandbox Code Playgroud)