Rust:实现泛型特征时出现 E0562

Posted

技术标签:

【中文标题】Rust:实现泛型特征时出现 E0562【英文标题】:Rust: E0562 when implementing generic trait 【发布时间】:2020-12-24 01:29:23 【问题描述】:

到目前为止,我正在尝试 Rust 和❤️。

但目前我被通用特征卡住了:)

现状:

我想实现这个特性,但我无法修改:

pub trait Handler<R, B, E> 
    fn run(&mut self, event: http::Request<B>) -> Result<R, E>;

同一库中该特征的一个实现是:

impl<Function, R, B, E> Handler<R, B, E> for Function
where
    Function: FnMut(http::Request<B>) -> Result<R, E>,

    fn run(&mut self, event: http::Request<B>) -> Result<R, E> 
        (*self)(event)
    

而这个实现可以如下使用:

fn handler(req: http::Request<Body>) -> Result<impl IntoResponse, MyError> 
    ...

使用IntoReponse 特征:

pub trait IntoResponse 
    fn into_response(self) -> Response<Body>;


我想做的事:

我想为结构实现该特征,以便能够与上述类型一起使用。

我试过了:

impl Handler<impl IntoResponse, Body, MyError> for GQLHandler 
    fn run(&mut self, req: http::Request<Body>) -> Result<impl IntoResponse, MyError> 
        ...
    

但这会导致错误:

error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
  --> handlers/gql.rs:18:14
   |
18 | impl Handler<impl IntoResponse, Body, NowError> for GQLHandler 
   |              ^^^^^^^^^^^^^^^^^

error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
  --> handlers/gql.rs:19:59
   |
19 |     fn run(&mut self, req: http::Request<Body>) -> Result<impl IntoResponse, NowError> 
   |                                                           ^^^^^^^^^^^^^^^^^

如果我为特定类型实现它是有原因的,例如

impl Handler<http::Response<Body>, Body, NowError> for GQLHandler 
    fn run(&mut self, req: http::Request<Body>) -> Result<http::Response<Body>, NowError> 

但我想以某种方式保留impl Trait

期待任何建议。

感谢和干杯 托马斯

编辑:

跟进@MaxV 的回答(谢谢!),遗憾的是这对我不起作用(这就是为什么我还没有接受这个回答)。

See this playground

当尝试使用实现 IntoResponse 的类型返回 Ok(...) 时,我收到以下错误:

  |
3 | impl<T: IntoResponse> Handler<T, Body, MyError> for GQLHandler 
  |      - this type parameter
4 |     fn run(&mut self, req: Request<Body>) -> Result<T, MyError> 
5 |         Ok(Response::<()>::new(()))
  |            ^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found struct `http::Response`
  |
  = note: expected type parameter `T`
                     found struct `http::Response<()>`

即使我为Response 实现了IntoResponse

trait IntoResponse
    fn foo(&self);


impl IntoResponse for Response<()>

    fn foo(&self) 

我错过了什么?

【问题讨论】:

【参考方案1】:

新答案

感觉你在找Existential types:

目前,不可能从 trait 实现返回 impl Trait 类型。这是此 RFC 修复的巨大限制 <...>

Existential types RFC 已合并,但实现不稳定。您可以跟踪进度there。

原答案

你不能在那里使用impl,但你可以这样解决它:

Playground

impl<T: IntoResponse> Handler<T, Body, MyError> for GQLHandler 
    fn run(&mut self, req: http::Request<Body>) -> Result<T, MyError> 
        // ...
    

【讨论】:

删除了我之前的评论,因为我相应地更新了原始问题。 嘿@thlcodes,您能解释一下为什么要避免使用Result&lt;http::Response&lt;Body&gt;, NowError&gt; 方法吗?解释应该可以帮助我为您找到最佳答案。 当然。 IntoResponse 也为Into&lt;Body&gt; 甚至serde_json::Value 实现,我也想将它们用于更简洁的代码。但主要是我想了解为什么这不起作用和学习:) @thlcodes,我已经更新了答案。请看一看。 在您的示例中,我无法返回实现 IntoResponse 的对象。这是my attempt。我得到“预期类型参数T,找到结构Return”即使我认为ReturnT。我做错了什么?

以上是关于Rust:实现泛型特征时出现 E0562的主要内容,如果未能解决你的问题,请参考以下文章

使用 sklearn 特征提取时出现内存错误

rust特征对象

尝试在 opencv 4.5.1 中使用 SIFT 提取特征时出现问题

编译 CUDA cuSolver 特征值示例时出现编译错误

在 Kotlin 中编写具有特征的 Android 测试时出现 java.lang.VerifyError

尝试将分类特征转换为数值时出现“ValueError:给定列不是数据框的列”