< 返回版块

Joey 发表于 2019-03-01 20:04

打算照着go的http api实现一个rust的web框架,目前写了点基础的代码见https://github.com/xcaptain/voyager.rs,但是遇到了问题导致路由部分写不下去了,rust对闭包的类型校验也是这么严格,错误信息如下,提示说考虑使用boxed closure或trait object但是搜了一下没找到类似的资料自己也还没想好怎么改代码,求懂行的大神赐教下

[email protected] ~/P/voyager> cargo run --example hello
   Compiling voyager v0.1.0 (/home/joey/Projects/voyager)
error[E0308]: mismatched types
  --> examples/hello.rs:20:49
   |
20 |     m.handle("/world".to_string(), Handler::new(world_handler));
   |                                                 ^^^^^^^^^^^^^ expected closure, found a different closure
   |
   = note: expected type `[[email protected]/hello.rs:10:25: 13:6]`
              found type `[[email protected]/hello.rs:14:25: 17:6]`
   = note: no two closures, even if identical, have the same type
   = help: consider boxing your closure and/or using it as a trait object

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: Could not compile `voyager`.

To learn more, run the command again with --verbose.

评论区

写评论
XG.Ley 2019-03-03 09:00

或许可以参考别人如何实现,actix web

@Joey 目前实现了一个简单的http框架,api已经很接近go的net/http了,这几天我再优化下看看能不能做一些更复杂的事情 use http::response::Builder; use http::{Request, Response}; use std::sync::Arc; use voyager::http as myhttp; use voyager::http::handler::Handler; use voyager::http::mux::Mux;

fn main() -> Result<(), Boxstd::error::Error> { let mut m = Mux::new();

let hello_handler = |w: &mut Builder, r: &Request<()>| -> Response<String> {
    let path = r.uri().path();
    w.body(format!("in hello handler, path is: {}", path))
        .unwrap()
};
let world_handler = |w: &mut Builder, r: &Request<()>| -> Response<String> {
    let path = r.uri().path();
    w.body(format!("in world handler, path is: {}", path))
        .unwrap()
};

m.handle("/hello".to_string(), Handler::new(Arc::new(hello_handler)));
m.handle("/world".to_string(), Handler::new(Arc::new(world_handler)));
return myhttp::listen_and_serve("127.0.0.1:8080".to_string(), m);

}

作者 Joey 2019-03-03 00:26

目前实现了一个简单的http框架,api已经很接近go的net/http了,这几天我再优化下看看能不能做一些更复杂的事情

use http::response::Builder;
use http::{Request, Response};
use std::sync::Arc;
use voyager::http as myhttp;
use voyager::http::handler::Handler;
use voyager::http::mux::Mux;

fn main() -> Result<(), Box<std::error::Error>> {
    let mut m = Mux::new();

    let hello_handler = |w: &mut Builder, r: &Request<()>| -> Response<String> {
        let path = r.uri().path();
        w.body(format!("in hello handler, path is: {}", path))
            .unwrap()
    };
    let world_handler = |w: &mut Builder, r: &Request<()>| -> Response<String> {
        let path = r.uri().path();
        w.body(format!("in world handler, path is: {}", path))
            .unwrap()
    };

    m.handle("/hello".to_string(), Handler::new(Arc::new(hello_handler)));
    m.handle("/world".to_string(), Handler::new(Arc::new(world_handler)));
    return myhttp::listen_and_serve("127.0.0.1:8080".to_string(), m);
}
作者 Joey 2019-03-03 00:22

感谢,我在官方论坛也问了这个问题,https://users.rust-lang.org/t/how-to-use-boxed-closure-or-trait-object/25786/5 现在确实已经修复了,按照回我的那几个人的说法如果要用trait的话就要加上dyn来表明可以接受任何实现了这个trait的结构,如果要用closure的话就要加上box这样闭包在编译时能知道大小。

用trait太麻烦相关的结构都要加上trait bound,所以改用了boxed closure.

@XG.Ley 看样子已经修好了。 具体使用可以看它的教程:https://doc.rust-lang.org/book/ch19-05-advanced-functions-and-closures.html

XG.Ley 2019-03-02 08:58

看样子已经修好了。

具体使用可以看它的教程:https://doc.rust-lang.org/book/ch19-05-advanced-functions-and-closures.html

1 共 4 条评论, 1 页