use async_trait::async_trait;
use std::future::Future;
#[async_trait]
trait Point{
async fn call(&self,input:&mut String) -> String;
}
#[async_trait]
impl <F,Fut>Point for F
where
F:Send+Sync+'static+Fn(&mut String) -> Fut,
Fut:Send+Sync+'static +Future<Output = String>
{
async fn call(&self,input:&mut String) -> String{
self(input).await
}
}
fn main(){
run(test);
}
fn run(_:impl Point){
}
async fn test(input:&mut String) -> String{
todo!()
}
编译后报错:
error: implementation of `FnOnce` is not general enough
--> src\life_time.rs:20:5
|
20 | run(test);
| ^^^ implementation of `FnOnce` is not general enough
|
::: C:\Users\Lexo\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\ops\function.rs:219:1
|
219 | / pub trait FnOnce<Args> {
220 | | /// The returned type after the call operator is used.
221 | | #[lang = "fn_once_output"]
222 | | #[stable(feature = "fn_once_output", since = "1.12.0")]
... |
227 | | extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
228 | | }
| |_- trait `FnOnce` defined here
|
= note: `FnOnce<(&'0 mut String,)>` would have to be implemented for the type `for<'_> fn(&mut String) -> impl Future {test}`, for some specific lifetime `'0`...
= note: ...but `FnOnce<(&mut String,)>` is actually implemented for the type `for<'_> fn(&mut String) -> impl Future {test}`
我不明白报错信息的意思?是生命周期推断失败了吗?
1
共 4 条评论, 1 页
评论区
写评论似乎这种情况必须要加生命周期的.有个issue有说明: use async_trait::async_trait; use std::future::Future; type MutString<'a> = &'a mut String; #[async_trait] trait Point<'a> { async fn call(&self, input: MutString<'a>) -> String; } #[async_trait] impl<'a, F, Fut> Point<'a> for F where F: Send + Sync + 'static + Fn(MutString<'a>) -> Fut, Fut: Send + Sync + 'static + Future<Output = String>, { async fn call(&self, input: MutString<'a>) -> String { self(input).await } } fn main() { let future = run(test); let result = async_std::task::block_on(future); println!("result={:?}", result); } async fn run<'a>(func: impl Point<'a>) -> String { "asdf".to_owned() } async fn test(input: &mut String) -> String { input.to_owned() }
高人
use async_trait::async_trait; use std::{future::Future, pin::Pin}; trait Point<'async_trait>{ fn call<'life0,'life1>(&'life0 self,input:&'life1 mut String) -> Pin<Box<dyn Future<Output =String>+Send>> where 'life0:'async_trait,'life1:'async_trait; } impl <'async_trait,F,Fut>Point<'async_trait> for F where F:Send+Sync+'static+Fn(&'async_trait mut String) -> Fut, Fut:Send+Sync+'static +Future<Output = String> { fn call<'life0,'life1>(&'life0 self,input:&'life1 mut String) -> Pin<Box<dyn Future<Output=String>+Send>> where 'life0:'async_trait, 'life1:'async_trait, { Box::pin(self(input)) } } fn main(){ run(test); } fn run<'async_trait>(_:impl Point<'async_trait>){ } async fn test(input:&mut String) -> String{ todo!() }
如果这样做,就能通过编译了
很奇怪的是,如果不用async,就能通过编译
use async_trait::async_trait; use std::future::Future; trait Point{ fn call(&self,input:&String) -> String; } impl <F>Point for F where F:Send+Sync+'static+Fn(&String) -> String, { fn call(&self,input:&String) -> String{ self(input) } } fn main(){ run(test); } fn run(_:impl Point){ } fn test(input:&String) -> String{ "todo!()".to_string() }