How do I return an instance of a trait from a method?
(3个答案)
Is it possible to use `impl Trait` as a function's return type in a trait definition?
(4个答案)
Why can impl trait not be used to return multiple / conditional types?
(2个答案)
去年关闭。
我具有actix_web
FromRequest
特征的以下实现:
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))
}
}
由于返回类型是
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做到这一点,在FnOnce中,实际实现仅在编译时生成(我认为)。
我知道我可以略微缩短类型定义,以使它们不完全合格,但是我想使用宏来生成此定义,据我所知,最好使用完整类型。
有没有更好的方法来确定 future 的返回?当前的定义是毛茸茸的。
FnOnce是一个特征,因此在编译时没有已知的大小。但是,我们可以将其包装在具有已知大小的Box中以进行编译:
impl ::actix_web::FromRequest for Box<dyn SessionRepository> {
type Error = ::actix_web::Error;
type Future = ::futures::future::MapOk<
::futures::future::Ready<Result<RealSessionRepository, Self::Error>>,
Box<dyn FnOnce(RealSessionRepository) -> Box<(dyn SessionRepository)>>,
>;
type Config = ();
fn from_request(
req: &::actix_web::HttpRequest,
payload: &mut actix_web::dev::Payload,
) -> Self::Future {
RealSessionRepository::from_request(&req, payload).map_ok(Box::new(|dep| Box::new(dep)))
}
}
我是一名优秀的程序员,十分优秀!