我真的不知道该怎么问这个问题,但有人能解释一下为什么会这样吗?
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=969cf50f66746c4aa3941200e01f1570
enum SlotFn<'a, Comp, Args = (), R = ()>
where Args: 'static,
R: Default + 'static,
{
SimpleFn(fn(Args) -> R),
MemberFn(fn(&'a Comp) -> R),
MemberFnMut(fn(&'a mut Comp, Args) -> R),
}
impl<'a, Comp, Args, R> SlotFn<'a, Comp, Args, R>
where Args: 'static,
R: Default + 'static,{
fn from_member(f: fn(&'a Comp) -> R) -> Self{
SlotFn::MemberFn(f)
}
fn from_member_mut(f: fn(&'a mut Comp, Args) -> R) -> Self {
SlotFn::MemberFnMut(f)
}
fn emit(&self, comp: &'a Comp, args: Args) -> R {
match self {
SlotFn::SimpleFn(f) => f(args),
SlotFn::MemberFn(f) => f(comp),
_ => Default::default()
}
}
fn emit_mut(&mut self, comp: &'a mut Comp, args: Args) -> R {
match self {
SlotFn::MemberFnMut(f) => f(comp, args),
_ => Default::default()
}
}
}
struct Test(u32);
impl Test {
fn reffunc(&self) {
println!("value: {}", self.0);
}
fn reffunc_mut(&mut self, val: u32) {
self.0 = val;
}
}
fn main() {
let mut test = Test(0);
let slot = SlotFn::from_member(Test::reffunc);
let mut mslot = SlotFn::from_member_mut(Test::reffunc_mut);
mslot.emit_mut(&mut test, 10);
slot.emit(&test, ());
}
enum SlotFn<'a, Comp, Args = (), R = ()>
where Args: 'static,
R: Default + 'static,
{
SimpleFn(Box<dyn Fn(Args) -> R + Send + Sync + 'static>),
MemberFn(Box<dyn Fn(&'a Comp) -> R + Send + Sync + 'static>),
MemberFnMut(Box<dyn FnMut(&'a mut Comp, Args) -> R + Send + Sync + 'static>),
}
impl<'a, Comp, Args, R> SlotFn<'a, Comp, Args, R>
where Args: 'static,
R: Default + 'static,{
fn from_member<F>(f: F) -> Self where F: Fn(&'a Comp) -> R + Send + Sync + 'static{
SlotFn::MemberFn(Box::new(f))
}
fn from_member_mut<F>(f: F) -> Self where F: FnMut(&'a mut Comp, Args) -> R + Send + Sync + 'static{
SlotFn::MemberFnMut(Box::new(f))
}
fn emit(&self, comp: &'a Comp, args: Args) -> R {
match self {
SlotFn::SimpleFn(f) => f(args),
SlotFn::MemberFn(f) => f(comp),
_ => Default::default()
}
}
fn emit_mut(&mut self, comp: &'a mut Comp, args: Args) -> R {
match self {
SlotFn::MemberFnMut(f) => f(comp, args),
_ => Default::default()
}
}
}
struct Test(u32);
impl Test {
fn reffunc(&self) {
println!("value: {}", self.0);
}
fn reffunc_mut(&mut self, val: u32) {
self.0 = val;
}
}
fn main() {
let mut test = Test(0);
let slot = SlotFn::from_member(Test::reffunc);
let mut mslot = SlotFn::from_member_mut(Test::reffunc_mut);
mslot.emit_mut(&mut test, 10);
slot.emit(&test, ());
}
在第二种情况下,我得到了以下错误:
error[E0502]: cannot borrow `test` as immutable because it is also borrowed as mutable
mutable borrow might be used here, when `mslot` is dropped and runs the destructor for type `SlotFn<'_, Test, u32>`
1条答案
按热度按时间kuarbcqp1#
我们把
from_member()
的'a
称为'a1
,把from_member_mut()
的'a
称为'a2
,如果'a1
和'a2
重叠,这是一个错误,test
被'a2
借用,而它被'a1
借用,那么'a1
和'a2
是什么呢?最短的时间是从创建
SlotFn
(对于每个SlotFn
)对象到销毁它,因为在这段时间内SlotFn
可以访问'a
的数据。在第一段代码中,我们可以提前销毁
SlotFn
,因为它们没有实现Drop
,因此在销毁时无法执行任何操作,因此无法观察到提前销毁。因此,在第一段代码中,编译器将'a1
和'a2
分别缩短到emit_mut()
和emit()
,因此它们不会冲突。然而在第二种情况下,它们可能实现了
Drop
-dyn Trait
总是被认为实现了Drop
,因为编译器不知道里面是什么-因此,它们的生命周期必须在块的末尾结束,因为Drop
可以观察到'a
。