当前位置: 首页 > 知识库问答 >
问题:

不能将实现特征的结构装箱为特征对象

鲁龙野
2023-03-14

我在和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
...
}

我收到错误消息:

在struct<code>filter::ContentFilter</code>中找到的预期特征对象<code>dyn filter::TFilter</code>

=注意:预期引用<代码>

这是误导性的:

  1. 它确实实现了该特征
  2. 编译器知道 ContentFilter 结构的大小

有线索吗?

另外,代码无论如何都不好(因为不清楚返回的盒子是谁的),但信息是误导性的。

缴费灵。那么如何实现缓存代理:

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;
    }
}

共有1个答案

程冥夜
2023-03-14

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

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

(操场上的最小编译版本)

这个盒子是在你的函数中新创建的,所以你必须返回这个盒子的所有权。不可能只返回对临时变量的引用,因为它会在函数结束时超出范围。

此更改的副作用是Box的未调整大小的强制

 类似资料:
  • 我有一个设计问题,当使用类似的东西时: 我认为应该有一些更好的方法来实现这种参数化的特性。 我在std中没有找到好的示例(例如,在具有类似的关联类型的traits中没有实现)?

  • 我正在尝试将DHT11库用于我的STM32F303VC 我得到错误: 我的错误图像: 我的代码在辅助模块中是: 我的main.rs代码是:

  • 我有一个这样的提供程序设置: 我正在尝试使用actix web中的内置方法,将 或类似的东西。 但是,我反而收到以下错误: 有人能帮我弄清楚怎么解决这个问题吗?我对std::marker::size做了一些研究,但我不知道如何使用它来解决这个问题。

  • 我对Java和OOP都是新手。但是,我使用notify读取一个特征,然后使用read读取回调中的多个特征。 我想知道,为什么在使用readCharacteristic(我的特征)时,只能从单个特征(除了通知的特征)中获取值。蓝牙gatt回调声明如下: 公共布尔值 (BluetoothGattCharacteristic characteristic characteristic)从相关远程设备读取

  • 将跟踪和跨度添加到Slf4J MDC,以便您可以从日志聚合器中的给定跟踪或跨度中提取所有日志。示例日志: 2016-02-02 15:30:57.902 INFO [bar,6bfd228dc00d216b,6bfd228dc00d216b,false] 23030 --- [nio-8081-exec-3] ... 2016-02-02 15:30:58.372 ERROR [bar,6bfd

  • 反缓存 anticache设置该选项后,它将删除可能引起服务器响应的Header(if-none-match和if-modified-since)304 not modified。当您要确保完全捕获HTTP交换时,这很有用。当您要确保服务器以完整的数据响应时,也经常在客户端重播期间使用它。 客户端重播 客户端重播可以做到:您提供了一个以前保存的HTTP对话,而mitmproxy则一个接一个地重播了