rust 删除所需的ToString trait时出错(借用的数据转义到方法外部)

jhdbpxl9  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(87)

我从我自己的“Custom”trait的泛型impl中删除了一个ToString trait需求。

impl<T : Any 
    // +ToString //uncommenting this removes the error
> CustomData for T { 
    fn as_any(&self) -> &dyn Any { self }    
}

字符串
其他地方:

impl CustomInstance {
    pub fn borrow<T:Any>(&self) -> Option<Ref<'_, T>>  {
        let b= self.data.borrow();

        if !b.as_any() //error here
            .is::<T>() 
        { 
            return None;
        }
        ..
    }
}


现在给出错误:

borrowed data escapes outside of method
`self` escapes the method body here


我发现一个类似的帖子“Trait problem: Borrowed data escapes outside of associated function
这似乎是说required(ToString)trait将生存期默认为static,但我不明白从哪里开始。
以下是完整的代码(它已从原始代码缩短):

use std::any::Any;
use std::cell::{RefCell, Ref};
use std::rc::Rc;

pub trait CustomData : Any { fn as_any(&self) -> &dyn Any; }

impl<T : Any 
    // +ToString //uncommenting this removes the error
> CustomData for T { 
    fn as_any(&self) -> &dyn Any { self }    
}

pub struct CustomInstance { data: Rc<RefCell<dyn CustomData>>, }

impl CustomInstance {
    pub fn borrow<T:Any>(&self) -> Option<Ref<'_, T>>  {
        let b= self.data.borrow();

        if !b.as_any() //error here
            .is::<T>() 
        { 
            return None;
        }
        
        Some(Ref::map(b, |c| c.as_any().downcast_ref::<T>().unwrap()))
    }
}

fn main() { }

ffscu2ro

ffscu2ro1#

问题是编译器认为您是在Ref本身上调用as_any(),而不是在它包含的数据上,并且由于Ref不是'static,它会抱怨。当您用ToString约束它时(Ref没有实现),它会为您引用它。
你所需要做的就是解引用Ref

pub fn borrow<T: Any>(&self) -> Option<Ref<'_, T>> {
    let b = self.data.borrow();

    if !(*b).as_any().is::<T>() {
        return None;
    }

    Some(Ref::map(b, |c| c.as_any().downcast_ref::<T>().unwrap()))
}

字符串
或者使用filter_map()

pub fn borrow<T: Any>(&self) -> Option<Ref<'_, T>> {
    let b = self.data.borrow();
    Ref::filter_map(b, |c| c.as_any().downcast_ref::<T>()).ok()
}

相关问题