我正在尝试为Arc<tokio::sync::RwLock<T>>
做一个新的类型 Package 器,我有一个with()
方法,它接受一个非闭包,这个方法工作得很好。
现在我想添加一个with_async()
方法,它接受一个codec闭包。但是编译器给出了一个错误。
这可能吗?
use std::sync::Arc;
use tokio::sync::RwLock;
use std::future::Future;
#[derive(Debug, Default)]
pub struct AtomicRw<T>(Arc<RwLock<T>>);
impl<T> From<T> for AtomicRw<T> {
fn from(t: T) -> Self {
Self(Arc::new(RwLock::new(t)))
}
}
impl<T> AtomicRw<T> {
// This compiles.
pub async fn with<R, F>(&self, f: F) -> R
where
F: FnOnce(&T) -> R,
{
let lock = self.0.read().await;
f(&lock)
}
pub async fn with_async<R, F>(&self, f: F) -> R
where
// Error: error[E0562]: `impl Trait` only allowed in function and inherent method argument and return types, not in `Fn` trait return types
F: FnOnce(&T) -> impl Future<Output = R>,
{
let lock = self.0.read().await;
f(&lock).await
}
}
#[tokio::main]
async fn main() {
struct Car {
year: u16,
}
let atomic_car = AtomicRw::from(Car{year: 2016});
atomic_car.with(|c| println!("year: {}", c.year)).await;
let _year = atomic_car.with(|c| c.year).await;
atomic_car.with_async(|c| async {
println!("year: {}", c.year)
}).await;
}
字符串
Playground
完整的错误是:
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types
--> src/main.rs:29:26
|
29 | F: FnOnce(&T) -> impl Future<Output = R>,
| ^^^^^^^^^^^^^^^^^^^^^^^
型
edit:我可以通过将fn改为这样来编译它:
pub async fn with_async<'a, R, F>(&'a self, f: impl FnOnce(&T) -> F ) -> R
where
F: Future<Output = R>,
{
let lock = self.0.read().await;
f(&lock).await
}
型
然而,当我尝试使用它时,我仍然得到一个关于生命周期的编译错误:
atomic_car.with_async(|c| async {
println!("year: {}", c.year)
error: lifetime may not live long enough
--> src/lib.rs:47:31
|
47 | atomic_car.with_async(|c| async move {
| ____________________________--_^
| | ||
| | |return type of closure `{async block@src/lib.rs:47:31: 50:6}` contains a lifetime `'2`
| | has type `&'1 Car`
48 | | println!("year: {}", c.year)
49 | |
50 | | }).await;
| |_____^ returning this value requires that `'1` must outlive `'2`
的字符串
1条答案
按热度按时间snvhrwxg1#
好的,我找到了一个有详细解释的解决方案here。
不幸的是,它似乎需要动态调度,调用者需要添加
.boxed()
并包含FutureExt
特征,所有这些都很糟糕。如果有人有一个更好的解决方案没有这些缺点,请张贴。
很好。
字符串
Playground的