Newbie learning to clap

I've started learning clap as prelude to going through "Command-line Rust" (which unfortunately uses a very old version). I got stuck on an early hurdle using Version 4. Parsing an arbitrary number of arguments:

let text: Vec<&String> = matches.get_many("text").unwrap().collect();
println!("{}", text.join(" "));

This throws up the compiler error:
the method join exists for struct Vec<&String>, but its trait bounds were not satisfied
the following trait bounds were not satisfied:
[&std::string::String]: Join<_>

Any thoughts?

join works for a Vec<&str> of Vec<String> but not Vec<&String>.

The relevant implementation is this which is a bit complicated to follow since it then goes into the Borrow trait, where Borrow<str> is not implemented for &String mainly just for reasons of "we haven't figured out a way to make it work whilst also offering this generic implementation".

That being said, you usually don't want to store &String references[1] anyways, and &str would be preferred over those.

Instead of needing to collect an intermediate Vec, you could also look into using the .join method for iterators in the itertools crate which also already supports types like &String anyways.

Or, for passing to println!, you can even skip the need to create an intermediate joined String by using the Itertools::format method.


  1. this convention only applies to immutable references - mutable references &mut String are fine and useful, and owned String values, too ↩ī¸Ž

2 Likes

Brilliant! Both methods worked.
Thanks very much, Steffahn!