gpt4 book ai didi

rust - 无法装箱将特征实现为特征对象的结构

转载 作者:行者123 更新时间:2023-12-03 11:44:06 25 4
gpt4 key购买 nike

我正在玩Rust,这是代码:

pub trait TFilter {
fn get_text(&self) -> &String;
}
...
pub struct ContentFilter {
text: String,
domains: String,
body: String,
}

impl TFilter for ContentFilter {
fn get_text(&self) -> &String {
return &self.text
}
}

impl ContentFilter {
pub fn from_text(text: String, domains: String, body: String) -> Self {
return ContentFilter {
text,
domains,
body
}
}
}
...

fn filter_from_text(&mut self, text: String) -> &Box<dyn TFilter> {
...
&Box::new(ContentFilter::from_text(text, domains, body)) // is returned
...
}
我收到错误消息:

expected trait object dyn filter::TFilter, found struct filter::ContentFilter


= note: expected reference &std::boxed::Box<(dyn filter::TFilter + 'static)>found reference &std::boxed::Box<filter::ContentFilter>


这具有误导性,因为:
  • 它确实实现了trait
  • 编译器确实知道ContentFilter结构
  • 的大小

    有什么线索吗?
    PS。无论如何,代码都不好(因为尚不清楚谁归还了Box),但是该消息具有误导性。
    PPS。然后如何实现缓存代理:
    pub trait TFilterBuilder {
    fn filter_from_text(&mut self, text: String) -> &Box<dyn TFilter>;
    }
    ...
    struct FilterCachingProxy {
    filter_builder: Box<dyn TFilterBuilder>,
    cache: Box<dyn TFilterCache>
    }

    impl FilterCachingProxy {
    fn new_for_builder(filter_builder: Box<dyn TFilterBuilder>, cache: Box<dyn TFilterCache>) -> Self {
    return FilterCachingProxy {
    filter_builder,
    cache
    }
    }
    }

    impl TFilterBuilder for FilterCachingProxy {
    fn filter_from_text(&mut self, text: String) -> &Box<dyn TFilter> {
    let boxed_filter = match self.cache.get(&text) {
    Some(found_boxed_filter) => found_boxed_filter,
    _ => {
    // delegate creation to wrapped TFilterBuilder impl (`filter_builder`)
    let boxed_filter = self.filter_builder.filter_from_text(text.clone());
    // ... and put to the cache
    self.cache.put(&text, &boxed_filter); // boxed_filter should be moved to make cache own it?
    &boxed_filter // looks strange: who owns it then?
    }
    };
    return boxed_filter;
    }
    }

    最佳答案

    返回类型应该只是Box,而不是对Box的引用:

    fn filter_from_text(&mut self, text: String) -> Box<dyn TFilter> {
    ...
    Box::new(ContentFilter::from_text(text, domains, body)) // is returned
    }
    ( Minimal compiling version on the playground)
    该框是在您的函数中新创建的,因此您必须返回该框的所有权。仅返回对临时变量的引用是不可能的,因为它将在函数末尾超出范围。
    此更改的副作用是,从 Box<ContentFilter>Box<dyn TFilter>的不定大小的强制现在将实际起作用。强制仅像返回值一样应用于强制位置。在您的代码中,需要强制的类型嵌套在引用中,因此编译器不会执行大小不一的强制。

    关于rust - 无法装箱将特征实现为特征对象的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65916882/

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