3 ms·
In general I agree that the difficulty and need to know the "gritty details" is overstated, but there is one aspect where that is true and I have found it confu
by thinkharderdev 4y ago
In general I agree that the difficulty and need to know the "gritty details" is overstated, but there is one aspect where that is true and I have found it confusing at times. Since it has to capture anything in scope of an await point, you will sometimes get somewhat non-obvious compiler errors about how "X is not Send" when it's not really obvious at all why it would need to be. So something like
```
let locked = std::sync::RwLock<Foo> = ...;
let lock = locked.write().unwrap();
bar.doSomethingAsync().await
```
will complain because `std::sync::RwLockWriteGuard` is not send. Just looking at the code it is not really clear why it should need to be. To understand why, you need to understand how the compiler transforms this code into a state machine and capture everything in scope of an await point in Struct that must be send (since it can shift to new thread when resuming). It makes sense when you understand what's happening under the hood but can be a bit baffling when you are starting out.
- justinpombrio 4y agoThat is tricky. It's also something you need to know when working with closures in Rust, which are for the same reason much harder to work with and understand than closures in other languages. I wonder whether it would have been better design for Rust closures to require an explicit capture list, like in C++, just to be more explicit about what is happening. (Not sure if/how that would translate to `await`.)
- thinkharderdev 4y agoYeah, I've been stung more than once by the `Fn/FnOnce` distinction