首页 > 解决方案 > 如何通过查看 rust 中的 Trait 定义来正确编写返回类型

问题描述

当我尝试将它们包装在其他函数中时,我正在思考如何确定函数的返回类型。

我有时会使用一种变通方法,其中我有一个结构体,其中的字段表示如果我可以编写封闭的父函数,我将传递什么。但这不能正常工作。

目前我正在尝试使用任何路由框架,例如镍/潮。它们都有中间件支持。

以镍为例(因为界面看起来很简单),一个简单的中间件如下所示:

fn logger_fn(req: &mut Request, res: Response) -> MiddlewareResult {
    println!("logging request from logger fn: {:?}", req.origin.uri());
    res.next_middleware()
}

文档中我可以看到impl.trait

我想要的只是将它包装在一个函数中。在像 golang 这样的其他语言中,我会写如下内容:

func ParentFunction() func(r Request, w Response) MiddlewareResult {
  return func (r Request, w Response) MiddlewareResult {...}
}

但在这种情况下,我无法弄清楚将返回值作为什么。

我试过这个:

fn add_header(is_internal: bool)-> Fn(&'r mut Request<'mw, 'conn, D>, Response<'mw, D>) -> MiddlewareResult<'mw, D> { 
    fn middleware_1(req: &mut Request, res: Response) -> MiddlewareResult {
        if is_internal {
            println!("internal");
            return res.next_middleware()
        }

        let auth_header = match req.origin.headers.get::<Authorization<Bearer>>() {
            Some(header) => header,
            None => panic!("No authorization header found")
        };

        let header = header::HeaderFormatter(auth_header).to_string();
        println!("Header v {}", header);
        res.next_middleware()
    }
}

我收到错误消息:

help: consider making the bound lifetime-generic with a new `'conn` lifetime
  |
4 | fn add_header(is_internal: bool)-> for<'conn> Fn(&'r mut Request<'mw, 'conn, D>, Response<'mw, D>) -> MiddlewareResult<'mw, D> {
  |                                    ^^^^^^^^^^

error[E0261]: use of undeclared lifetime name `'mw`
 --> src/main.rs:4:80
  |
4 | fn add_header(is_internal: bool)-> Fn(&'r mut Request<'mw, 'conn, D>, Response<'mw, D>) -> MiddlewareResult<'mw, D> {
  |                                                                                ^^^ undeclared lifetime
  |
  = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
help: consider introducing lifetime `'mw` here
  |
4 | fn add_header<'mw>(is_internal: bool)-> Fn(&'r mut Request<'mw, 'conn, D>, Response<'mw, D>) -> MiddlewareResult<'mw, D> {
  |              ^^^^^
help: consider making the bound lifetime-generic with a new `'mw` lifetime
  |

这是有道理的,因为我不知道如何使用这些生命周期变量以及用什么替换 D。

这在我使用的任何库中都是如此。我无法理解这部分语言。

我需要一些关于如何做到这一点的帮助,找出返回类型。

标签: rustnickel

解决方案


您要查找的内容称为闭包,但您实际上想要返回的是实现Middleware的对象。

Nickel库还有一个名为middleware的实用宏来确保你的宏实现了Middleware trait,没有它就需要编写大量的样板代码。

这是一个可以工作的代码片段:

fn add_header<D>(is_internal: bool) -> impl Middleware<D> {
    middleware! { |req, res| 
        if is_internal {
            println!("internal");
            return res.next_middleware()
        }

        let auth_header = match req.origin.headers.get::<Authorization<Bearer>>() {
            Some(header) => header,
            None => panic!("No authorization header found")
        };

        let header = header::HeaderFormatter(auth_header).to_string();
        println!("Header v {}", header);
    }
}

我建议您阅读有关闭包的 rust 书籍以获取更多信息:
闭包:可以捕获其环境的匿名函数有一个名为move
的关键字的信息在使用这种类型时很重要。


推荐阅读