Issues with typing

I have this:

    let chunks: Chunks<'_, String> = groups.chunks(groups.len() / 6).into_iter();

    let handles = chunks
        .map(|chunk: &[String]| {
            let s = mpsc::Sender::clone(&sender);
            let v = chunk.to_owned().into_iter();
            spawn(move || {
                let count = v
                    .map(|line| line.matches("b").count())
                    .sum::<usize>();
                s.send(count).unwrap();
            })
        })
        .collect();

The collect() call demands I type "handles" (I'm surprised it can't be inferred) but I cannot figured out how to type it correctly.

It implies it should be this:

but of course that cannot be used directly.

You probably want something like

let handles: Vec<_> = chunks ...

or

...
    .collect::<Vec<_>>();

where Vec<_> represents the container you want to collect into, and could perhaps also be VecDeque<_> or something for example (hence why it's ambiguous).

5 Likes

Incidentally, when your IDE isn't being helpful, try cargo check.

error[E0282]: type annotations needed
 --> src/main.rs:8:9
  |
8 |     let handles = chunks
  |         ^^^^^^^
  |
help: consider giving `handles` an explicit type
  |
8 |     let handles: Vec<_> = chunks
  |                ++++++++

For more information about this error, try `rustc --explain E0282`.
4 Likes

Thanks! That did the trick.

Can I piggy-back another question onto this thread? Yes? Great.

I join on all the sending threads, and then explicitly drop() the original sender, then process all values in the receiver, yet the main thread does not terminate - why?

I don't know. If you missed dropping a sender somewhere, that could do it, if your receiver is blocking (which it sounds like you understand since you drop the original sender right away).

It probably won't help that problem, but consider joining your threads after processing all the values in the receiver, so your main thread can do some work while the spawned threads are also still doing work. Or just dropping the handles for that matter.

Seems to me that this should do it but it doesn't. Main thread continues.

    for num in receiver {
        println!("num: {}", num);
    }

    for h in handles {
        h.join().unwrap();
    }
    drop(sender);

No, drop the sender first. As long as it's alive, the receiver will block waiting for it to send more stuff.

    drop(sender);
    for num in receiver {
        println!("num: {}", num);
    }
5 Likes

I just discovered that independently!

Actually, IDE is showing not the type of the output of collect, but the type of its input, or, more precisely, the type of the expression before the annotation (chunks.map(...)).

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.