Self; fn consume(self) -> u8; } struct F-6ren">
gpt4 book ai didi

rust - 为什么这个借用仍然是 "active"?

转载 作者:行者123 更新时间:2023-12-03 14:39:48 24 4
gpt4 key购买 nike

这是我遇到的事情的简化示例:

trait Bla<'a> {
fn create(a: &'a Foo) -> Self;
fn consume(self) -> u8;
}

struct Foo;
impl Foo {
fn take(&mut self, u: u8) {}
}

struct Bar {
foo: Foo,
}

impl Bar {
fn foobar<'a, 'b, B: Bla<'b>>(&'a mut self)
where 'a: 'b {
let u = {
// immutable borrow occurs here
// type annotation requires that `self.foo` is borrowed for `'b`
let foo: &'b Foo = &self.foo;
let b = B::create(foo);
b.consume()
};

// error[E0502]: cannot borrow `self.foo` as mutable because it is also borrowed as immutable
self.foo.take(u);
}
}

为什么是 self.foo即使在退出它被借用的块后仍然被认为是借用的,使用借用的所有东西也被删除了?

最佳答案

数据可能会流向另一个地方。
要理解为什么编译器认为不可变借用可能仍然存在是正确的,请考虑以下 Bla 的实现。这是有效的:

#![feature(once_cell)]

// The data stored in this global static variable exists for the entirety of runtime.
static REFS: SyncLazy<Mutex<Vec<&'static Foo>>> = SyncLazy::new(|| Mutex::new(vec![]));

struct Bad;
impl Bla<'static> for Bad {
fn create(a: &'static Foo) -> Self {
// The reference can go somewhere other than `Self`!
REFS.lock().unwrap().push(a);
Bad
}

fn consume(self) -> u8 {
// Even if `self` is consumed here,
// `self` doesn't necessarily destory the immutable borrow.
0
}
}
当您的通用 foobar函数接受 Bla 的任何有效实现,有效的实现可能需要 &'static借用保证借用持续整个运行时。因此,它 一个错误,因为 consume不保证不可变借用消失。

您可能正在寻找 for<>语法,因为这将允许 Bad实现存在,但将禁止任何人调用 foobarBad :
impl Bar {
fn foobar<B: for<'b> Bla<'b>>(&mut self) {
let u = {
let foo: &Foo = &self.foo;
let b = B::create(foo);
b.consume()
};
self.foo.take(u);
}
}
fn main() {
Bar::foobar::<Bad>(&mut Bar { foo: Foo })
// ^ error: implementation of `Bla` is not general enough
// | `Bad` must implement `Bla<'0>`, for any lifetime `'0`...
// | ...but it actually implements `Bla<'static>`
}
如果不是这种情况,您可能需要提供更多实现细节而不是导致诊断错误的示例。

关于rust - 为什么这个借用仍然是 "active"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67147129/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com