質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

Q&A

解決済

2回答

1867閲覧

クロージャがブロックを返すとはどういう意味か

LEGEND

総合スコア9

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

1グッド

1クリップ

投稿2021/06/16 17:24

疑問

https://caddi.tech/archives/1997において「asyncブロックを返す普通のクロージャである。」とあるが、ブロックを返すということがよくわからない。どういう意味でしょうか?

わかっている点

クロージャはキャプチャした変数を要素に持ちFnOnceやFnMutやFnのトレイトを実装しているなにかだとは分かっていますが、前述した文章と結びつきません

わからない点

ブロックを返すという言葉の意味
asyncブロックというものの存在

調べたこと

https://doc.rust-jp.rs/book-ja/ch13-01-closures.htmlを読んだのですがそれっぽいことが書いてなかった

equal-l2👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

既に回答がついていますがブロックについて補足します。Rustのブロックは最後に評価した式がそのブロックの返り値となります。例えば以下のようにブロックを {let x = 3; x + 1} と書いた場合、最後の x + 1 がこのブロックの返り値となり y は 4に束縛されます。

rust

1fn main() { 2 let x = 5; 3 4 let y = { 5 let x = 3; 6 x + 1 7 }; 8 9 println!("The value of y is: {}", y); 10}

これは公式ドキュメントの関数の箇所に記述があります。

このようにブロックも式となっているので関数(やクロージャ)の末尾にブロックを置くことでブロックを評価した結果の値を関数(やクロージャ)の返り値とできます。このことを指して「ブロックを返す」と表現するのは納得できるでしょう。

async ブロックも(async ブロックはそれ自体が1つの式となる違いはありますが)同様に式であり、評価した結果の値があり、関数やクロージャの返り値とできます。そのことを指して「async ブロックを返す」と表現しているのでしょう。
因みに async ブロックについては公式ドキュメントの1つ、async bookに記述がありますがまだ和訳はされていません。

投稿2021/06/17 04:08

blackenedgold

総合スコア468

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tatsuya6502

2021/06/17 04:59

> asyncブロックはそれ自体が1つの式となる違いはありますが 「asyncブロックを返す」という表現がRustの世界で一般的かどうかは私にはわからないのですが、そう表現したくなるのは上の違いによるものかもしれません。 普通のブロックが返す値は、そのブロックの中身を評価した結果の値です。一方、asyncブロックが返す値は、ブロックの中身を後で評価するためのFuture値(Futureトレイトをを実装した匿名型の値)です。その値が返った時点ではまだブロックの中身が実行されていません。ですから値の中にブロックの中身全体が含まれているようなイメージが持てます。 これはクロージャが返されたとき似たようなイメージでしょうか(クロージャもクロージャトレイトを実装した匿名型の値) そういうイメージを持ちながら文章を書いたりすると、「asyncブロックを返す」という表現になるのかなと思いました。
LEGEND

2021/06/17 07:01

お二人の回答が私のわからない点、引っかかってる点を的確に突いてきて、非常にわかりやすいです 分かりやすい回答とてもありがとうございます
guest

0

Rustには、非同期ブロックというものがあり

rust

1let async_block = async { 2 // ... codes 3};

のように書くと、Futureトレイトを実装した型が帰ってきます。よって、

rust

1let return_async_block_closure = || async { 2 // ... codes 3};

のように書くと、これはFutureトレイトを実装した型を返す、クロージャーになります。これを、「asyncブロックを返す普通のクロージャである。」と言ったのでしょう。そして

rusts

1let lifetime_problem_closure = |a| async { a + 1 };

そして、このように書くとaのライフタイムが問題になります。引数aは非同期ブロック(Futureトレイトを実装した型)のライフタイムまで生きないといけないけど、aはクロージャーのライフタイムであるため。

投稿2021/06/16 20:18

nobkz

総合スコア320

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問