我有一个在内部使用hyper的库。我希望用户能够创建一个App
,其中包含一个内部Server
来处理HTTP连接。
use hyper::server::conn::AddrIncoming;
use hyper::server::Server;
use hyper::service::service_fn_ok;
use std::net::SocketAddr;
pub struct App {
inner: Server<AddrIncoming, ()>,
}
impl App {
pub fn new() -> Self {
let addr = SocketAddr::from(([0, 0, 0, 0], 3000));
let inner = Server::bind(&addr).serve(|| service_fn_ok(|_req| unimplemented!()));
App { inner }
}
}
该错误是预期的:
error[E0308]: mismatched types
--> src/lib.rs:15:15
|
15 | App { inner }
| ^^^^^ expected (), found closure
|
= note: expected type `hyper::server::Server<_, ()>`
found type `hyper::server::Server<_, [closure@src/lib.rs:13:47: 13:88]>`
虽然没有充分的文档说明,但是Server
的第二种类型参数是它使用的MakeService
的类型。
我不知道如何用inner
类型引用闭包。有什么办法可以使闭合框装起来以使代码编译?有没有办法手动实现MakeService
而不是使用闭包?
超级文档引用函数make_service_fn
,该函数返回MakeServiceFn
,但是该类型不是公共的,因此我不能在inner
的类型中使用它。
答案 0 :(得分:0)
问题是由于类型不匹配。在Rust中,类型参数是结构类型的一部分,因此结构中服务器的类型参数必须与您在结构中定义的参数匹配。就您而言,他们没有。
您的问题有2种解决方案。
pub struct App<T> {
inner: Server<AddrIncoming, T>,
}
现在,您将能够为服务器的第二类型参数创建具有不同类型的应用
在您的情况下,第二个参数的类型为``,因此您将这样声明结构:
type Service = ?; // This is really hard to find in this case.
pub struct App {
inner: Server<AddrIncoming, Service>,
}
在您的情况下,我建议您使用第一个参数,因为Server
的第二个类型参数的类型很难找到,并且在您的程序开发过程中很可能会发生变化,因此拥有它会容易得多结构上的类型参数。
但是,如果您不知道服务器的类型参数没有实现某些特征,有时您将无法在服务器上使用某些方法,因此可以将这些特征添加到类型参数中,如下所示:< / p>
pub struct App<T: Service> {
inner: Server<AddrIncoming, T>,
}
建议不要将类型参数放在结构本身上,而应仅将其放在impl
块上:
pub struct App<T> {
inner: Server<AddrIncoming, T>,
}
impl App<T: Service> {
// Here you'll be able to use the method from Server where T has to be a Service.
}
您还可以对以下功能执行相同的操作:
pub struct App<T> {
inner: Server<AddrIncoming, T>,
}
fn some_function(app: App<T: Service>) {
// Here you'll be able to use the method from Server where T has to be a Service
}