RustでFutureなクロージャを関数の引数にしてみる
目的
RustでFutureなクロージャを関数の引数にしてみる。
コード
main.rs
use std::future::Future;
async fn example<Fut>(f: impl FnOnce(i32, i32) -> Fut) -> i32
where
Fut: Future<Output = i32>,
{
f(1, 2).await
}
async fn example2<Fut>(f: impl FnOnce(i32, i32) -> Fut) -> String
where
Fut: Future<Output = String>,
{
f(1, 2).await
}
async fn example3<Fut>(f: impl FnOnce(String, String) -> Fut) -> String
where
Fut: Future<Output = String>,
{
f("xxx".to_owned(), "yyy".to_owned()).await
}
async fn example4<Fut>(aaa: &str, f: impl FnOnce(String, String) -> Fut) -> String
where
Fut: Future<Output = String>,
{
f("xxx".to_owned(), aaa.to_owned()).await
}
async fn example5<Fut>(f: impl FnOnce(&str) -> Fut) -> i32
where
Fut: Future<Output = i32>,
{
f("xxx").await
}
fn example6(f: impl FnOnce(&str) -> i32) -> i32
{
f("xxx")
}
#[tokio::main]
async fn main() {
let z = 3;
let res = example(|x, y| async move { x + y + z }).await;
println!("Hello, world! {}", res);
let res = example2(|x, y| async move { format!("{},{},{}", x, y, z) }).await;
println!("Hello, world! {}", res);
let res = example3(|x, y| async move { format!("{},{},{}", x, y, z) }).await;
println!("Hello, world! {}", res);
let res = example4("xyz", |x, y| async move { format!("{},{},{}", x, y, z) }).await;
println!("Hello, world! {}", res);
//let res = example5(|x| async move { x.len() as i32 }).await;
//println!("Hello, world! {}", res);
let res = example5(|_x| async move { 999 }).await;
println!("Hello, world! {}", res);
let res = example6(|x| { x.len() as i32 });
println!("Hello, world! {}", res);
}
解説
example1
main.rs
use std::future::Future;
async fn example<Fut>(f: impl FnOnce(i32, i32) -> Fut) -> i32
where
Fut: Future<Output = i32>,
{
f(1, 2).await
}
async fn example2<Fut>(f: impl FnOnce(i32, i32) -> Fut) -> String
where
Fut: Future<Output = String>,
{
f(1, 2).await
}
async fn example3<Fut>(f: impl FnOnce(String, String) -> Fut) -> String
where
Fut: Future<Output = String>,
{
f("xxx".to_owned(), "yyy".to_owned()).await
}
async fn example4<Fut>(aaa: &str, f: impl FnOnce(String, String) -> Fut) -> String
where
Fut: Future<Output = String>,
{
f("xxx".to_owned(), aaa.to_owned()).await
}
async fn example5<Fut>(f: impl FnOnce(&str) -> Fut) -> i32
where
Fut: Future<Output = i32>,
{
f("xxx").await
}
fn example6(f: impl FnOnce(&str) -> i32) -> i32
{
f("xxx")
}
#[tokio::main]
async fn main() {
let z = 3;
let res = example(|x, y| async move { x + y + z }).await;
println!("Hello, world! {}", res);
let res = example2(|x, y| async move { format!("{},{},{}", x, y, z) }).await;
println!("Hello, world! {}", res);
let res = example3(|x, y| async move { format!("{},{},{}", x, y, z) }).await;
println!("Hello, world! {}", res);
let res = example4("xyz", |x, y| async move { format!("{},{},{}", x, y, z) }).await;
println!("Hello, world! {}", res);
//let res = example5(|x| async move { x.len() as i32 }).await;
//println!("Hello, world! {}", res);
let res = example5(|_x| async move { 999 }).await;
println!("Hello, world! {}", res);
let res = example6(|x| { x.len() as i32 });
println!("Hello, world! {}", res);
}
example1
Futureなクロージャーを引数で受ける方法はスタックオーバーフローのカービーが教えてくれた(自分が質問したわけじゃないけど)。example1はクロージャーの引数も戻り値もCopyできるもの。
example2
戻り値だけCopyできないもの
example3
引数もCopyできない。さらに借用ではない
example4
呼び出す関数に借用な引数を与えてみる
example5
クロージャーの引数を借用にしてみる。借用した値をクロージャーの中で使うとエラーになる。使わないなら動作する。
error: borrowed data cannot be stored outside of its closure
--> src/main.rs:58:39
|
58 | let res = example5(|x| async move { x.len() as i32 }).await;
| ------------------------^^^^^^^^^^^^^^^^^^-------
| | | |
| | | cannot be stored outside of its closure
| | ...because it cannot outlive this closure
| borrowed data cannot be stored into here...
error: aborting due to previous error
example6
Futureでないクロージャーなら借用を利用しても問題無い
関連リンク
Author And Source
この問題について(RustでFutureなクロージャを関数の引数にしてみる), 我々は、より多くの情報をここで見つけました https://qiita.com/aoyagikouhei/items/a19fc2018f674a5b350b著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .