比较 Rust 中异步操作的句柄与流。

huangapple go评论86阅读模式
英文:

Comparing handles vs streams for async operations in rust

问题

In rust, we can write a vector of handles that allows to have asynchronous operation without blocking:

  1. use tokio;
  2. #[derive(Clone)]
  3. struct Cont {
  4. delta: usize,
  5. }
  6. impl Cont {
  7. fn get(&mut self) -> usize {
  8. self.delta
  9. }
  10. }
  11. #[tokio::main]
  12. async fn main() {
  13. let delta = 3;
  14. let cont = Cont { delta };
  15. let mut handles = Vec::new();
  16. for i in 0..10 {
  17. let mut cont = cont.clone();
  18. handles.push(tokio::spawn(async move {
  19. cont.get() + i.clone()
  20. }));
  21. }
  22. let _response = futures::future::join_all(handles).await;
  23. }

But this builds a vector of handles which might be considered a negative.

The stream version would replace the main with

  1. #[tokio::main]
  2. async fn main() {
  3. let delta = 3;
  4. let cont = Cont { delta };
  5. let stream = stream::iter(0..10).then(|i| async move {
  6. cont.clone().get() + i.clone()
  7. });
  8. let _result : Vec<usize> = stream.collect().await;
  9. }

Unfortunately, it does not compile.

So my questions are the following:

  • Is it possible to have the stream version of the code working correctly, that is, is there a way to clone the cont?
  • Apart from the building of a vector of handles, which does not occur in the stream version, are both versions the same? I mean, are they both based on green threads?
英文:

In rust, we can write a vector of handles that allows to have asynchronous operation without blocking:

  1. use tokio;
  2. #[derive(Clone)]
  3. struct Cont {
  4. delta: usize,
  5. }
  6. impl Cont {
  7. fn get(&amp;mut self) -&gt; usize {
  8. self.delta
  9. }
  10. }
  11. #[tokio::main]
  12. async fn main() {
  13. let delta = 3;
  14. let cont = Cont { delta };
  15. let mut handles = Vec::new();
  16. for i in 0..10 {
  17. let mut cont = cont.clone();
  18. handles.push(tokio::spawn(async move {
  19. cont.get() + i.clone()
  20. }));
  21. }
  22. let _response = futures::future::join_all(handles).await;
  23. }

But this builds a vector of handles which might be considered a negative.

The stream version would replace the main with

  1. #[tokio::main]
  2. async fn main() {
  3. let delta = 3;
  4. let cont = Cont { delta };
  5. let stream = stream::iter(0..10).then(|i| async move {
  6. cont.clone().get() + i.clone()
  7. });
  8. let _result : Vec&lt;usize&gt; = stream.collect().await;
  9. }

Unfortunately, it does not compile.

So my questions are the following:

  • Is it possible to have the stream version of the code working correctly, that is, is there a way to clone the cont?
  • Apart from the building of a vector of handles, which does not occur in the stream version, are both versions the same? I mean, are they both based on green threads?

答案1

得分: 1

Sure, here's the translated code portion:

是的,可以做到:

  1. fn main() {
  2. let delta = 3;
  3. let cont = Cont { delta };
  4. let stream = futures::stream::iter(0..10).then(move |i| {
  5. let mut cont = cont.clone();
  6. async move { cont.get() + i.clone() }
  7. });
  8. let _result: Vec<usize> = stream.collect().await;
  9. }

基本上只需在闭包中克隆 cont,然后将其移动到异步块中。

是的,它们在功能上是等效的。

英文:

Yup, it's doable:

  1. fn main() {
  2. let delta = 3;
  3. let cont = Cont { delta };
  4. let stream = futures::stream::iter(0..10).then(move |i| {
  5. let mut cont = cont.clone();
  6. async move { cont.get() + i.clone() }
  7. });
  8. let _result: Vec&lt;usize&gt; = stream.collect().await;
  9. }

Basically just clone the cont in the closure and then move it to the async block.

And yes, they are functionally equivalent.

huangapple
  • 本文由 发表于 2023年5月13日 19:52:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76242578.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定