generics - Rust:实现通用特征时出现 E0562

标签 generics rust traits

我正在试用 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) {}
}

我错过了什么?

最佳答案

新答案

感觉是在找Existential types :

Right now, it isn't possible to return an impl Trait type from a trait implementation. This is a huge restriction which this RFC fixes <...>

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> {
        // ...
    }
}

关于generics - Rust:实现通用特征时出现 E0562,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63746854/

相关文章:

Java - 未单独指定实例化的类范围泛型类型

java - 根据泛型接口(interface)的实现限制java中的泛型类型

binaryfiles - 用于检查 .rlib 二进制文件的 Rust 库

generics - 取决于特征的通用实现

java - 在这种情况下,如何参数化我的 Class 参数?

java - 为什么在泛型中需要 "? extends"

rust - 在 Rust 中打印路径

rust - 如何在不知道编译时结构的情况下读取CSV数据?

rust - 如何创建一个对各种整数类型通用的 is_prime 函数?

function - 如何使用关联常量来定义数组的长度?