Can thread::spawn function take a scope?

I am new to Rust's concurrent programming. I have been following a book about rust concurrency by Mara Bos.

While reading the book I found this code snippet:

let a = Arc::new([1, 2, 3]);

thread::spawn({
    let a = a.clone();
    move || {
          dbg!(a);
    }
});

dbg!(a);

From this code snippet, it seems that thread::spawn takes a scope, inside of it a is cloned by shadowing, and a closure takes the a variable.

Here is how the thread::spawn function looks like:

pub fn spawn<F, T>(f: F) -> JoinHandle<T>
where
    F: FnOnce() -> T + Send + 'static,
    T: Send + 'static,

So thread::spawn takes only closure. How can it take a scope while it declaration says it can take only a closure?

Thanks.

All blocks evaluate to their last expression. This works too:

let x: i32 = {
    println!("a block can contain many expressions");
    42
};
assert_eq!(x, 42);

This is not true; it says any type that implements FnOnce. That also includes fn items and function pointers.

6 Likes

Could you please explain it further? How it is related block inside the thread::spawn function?

It's not related, it's a separate observation that corrects another misunderstanding you had.

2 Likes

The "scope" (block) evaluates to a closure in the example.

Recall that Rust is an expression oriented language, which is why you don't need explicit returns at the end of functions or if/else blocks, etc.[1]


  1. "How can I define this function as a block when it says it can only return a String?" ↩ī¸Ž

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.