我有以下 actix_webFromRequest
特征的实现:
impl ::actix_web::FromRequest for Box<dyn SessionRepository> {
type Error = ::actix_web::Error;
type Future =
::futures::future::MapOk<::futures::future::Ready<Result<Self, Self::Error>>, ???>;
type Config = ();
fn from_request(
req: &::actix_web::HttpRequest,
payload: &mut actix_web::dev::Payload,
) -> Self::Future {
RealSessionRepository::from_request(&req, payload).map_ok(|dep| Box::new(dep))
}
}
由于返回类型是 an FnOnce
,我无法弄清楚如何实际设置返回类型。根据错误消息,它应该是FnOnce<(std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)>,)>
,但是这告诉我这fnOnce
是无效的,因为它在编译时不是已知的大小。
RealSessionRepository::from_request
返回一个未来,也是该FromRequest
特征的实现。
像这样插入 FnOnce 定义:
impl ::actix_web::FromRequest for Box<dyn SessionRepository> {
type Error = ::actix_web::Error;
type Future = ::futures::future::MapOk<
::futures::future::Ready<Result<Self, Self::Error>>,
FnOnce(RealSessionRepository) -> Box<(dyn SessionRepository + 'static)>,
>;
type Config = ();
fn from_request(
req: &::actix_web::HttpRequest,
payload: &mut actix_web::dev::Payload,
) -> Self::Future {
RealSessionRepository::from_request(&req, payload).map_ok(|dep| Box::new(dep))
}
}
给出以下一组错误消息:
error[E0277]: the size for values of type `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)` cannot be known at compilation time
--> api-server\src\db\sessions.rs:32:6
|
32 | impl ::actix_web::FromRequest for Box<dyn SessionRepository> {
| ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required because of the requirements on the impl of `core::future::future::Future` for `futures_util::future::try_future::map_ok::MapOk<futures_util::future::ready::Ready<std::result::Result<std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)>, actix_web::Error>>, (dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)>`
error[E0277]: expected a `std::ops::FnOnce<(std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)>,)>` closure, found `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)`
--> api-server\src\db\sessions.rs:32:6
|
32 | impl ::actix_web::FromRequest for Box<dyn SessionRepository> {
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)>,)>` closure, found `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)`
|
= help: the trait `std::ops::FnOnce<(std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)>,)>` is not implemented for `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)`
= note: required because of the requirements on the impl of `core::future::future::Future` for `futures_util::future::try_future::map_ok::MapOk<futures_util::future::ready::Ready<std::result::Result<std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)>, actix_web::Error>>, (dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)>`
error[E0277]: the size for values of type `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)` cannot be known at compilation time
--> api-server\src\db\sessions.rs:34:5
|
34 | / type Future = ::futures::future::MapOk<
35 | | ::futures::future::Ready<Result<Self, Self::Error>>,
36 | | FnOnce(RealSessionRepository) -> Box<(dyn SessionRepository + 'static)>,
37 | | >;
| |______^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required by `futures_util::future::try_future::map_ok::MapOk`
error[E0277]: the size for values of type `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)` cannot be known at compilation time
--> api-server\src\db\sessions.rs:40:5
|
40 | / fn from_request(
41 | | req: &::actix_web::HttpRequest,
42 | | payload: &mut actix_web::dev::Payload,
43 | | ) -> Self::Future {
44 | | RealSessionRepository::from_request(&req, payload).map_ok(|dep| Box::new(dep))
45 | | }
| |_____^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::ops::FnOnce(db::sessions::RealSessionRepository) -> std::boxed::Box<(dyn db::sessions::SessionRepository + 'static)> + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required by `futures_util::future::try_future::map_ok::MapOk`
MRE 可在:https ://github.com/zlepper/actix_web_mre 获得,因为它需要 actix,而在 rust 操场上不可用。
这特别是关于当我想要一个动态特征引用时如何处理这个问题,在一个我不拥有的关联类型中,因此不能做很多改变。更具体地说,我将如何使用 FnOnce 执行此操作,其中实际实现仅在编译时生成(我认为)。
我知道我可以稍微缩短类型定义,因此它们不是完全限定的,但是这是我想使用宏生成的东西,所以据我所知,最好使用完整类型。
有没有更好的方法来输入未来的回报?目前的定义是相当毛茸茸的..