I've made an iterator that gets data from crossbeam::Receiver and then should join the thread, by calling .join()
on the JoinHandle
instance.
I first tried to put .join()
into next()
method, but it caused an error: "can't move out of self.th
which is behind a mutable reference." I tried to put it into drop
-- because supposed it should destroy the object, but it made the same error.
struct BgIterator {
th: thread::JoinHandle<Result<(), BgIterError<OsmObj>>>,
rc: crossbeam::Receiver<OsmObj>
}
impl Drop for BgIterator {
fn drop(&mut self) {
self.th.join();
}
}
Compilation error:
error[E0507]: cannot move out of `self.th` which is behind a mutable reference
--> src/main.rs:316:3
|
316 | self.th.join();
| ^^^^^^^ move occurs because `self.th` has type `JoinHandle<Result<(), BgIterError<OsmObj>>>`, which does not implement the `Copy` trait
No matter what other tricks I played, it always hit this "can't move out..." issue.
-
Box
-ing - having
Option<JoinHandle<...>>
type and trying to pop the object - calling
as_ref
on it - calling
as_mut
(as suggested here) - unpacking into vars
-
if let Some(th) = self.th.as_mut() {
-- from here, same error - naive
let (th, self.th) = (self.th, None)
-- same error
What's the way to solve this?
Doing self.th.take()
(from here) actually does the trick, but is there a more direct way?
[added] A more direct approach I found here, using swap
or mem::take
.