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<http::Response<Body>, NowError>
方法吗?解释应该可以帮助我为您找到最佳答案。
当然。 IntoResponse
也为Into<Body>
甚至serde_json::Value
实现,我也想将它们用于更简洁的代码。但主要是我想了解为什么这不起作用和学习:)
@thlcodes,我已经更新了答案。请看一看。
在您的示例中,我无法返回实现 IntoResponse
的对象。这是my attempt。我得到“预期类型参数T
,找到结构Return
”即使我认为Return
是T
。我做错了什么?以上是关于Rust:实现泛型特征时出现 E0562的主要内容,如果未能解决你的问题,请参考以下文章
尝试在 opencv 4.5.1 中使用 SIFT 提取特征时出现问题