TLDR:
Since map() transforms one iterator into another iterator, you should provide an iterator first.
Try this:
fn example(books: Vec<usize>, n_books: usize) -> String {
books[0..n_books]
.iter()
.map(|u| u.to_string())
.collect::<Vec<_>>()
.join(" ")
}
fn main() {
let books: Vec<usize> = vec![1, 2, 3];
let n_books: usize = 2;
let result = example(books, n_books);
println!("{}", result); //"1 2"
}
Notes:
You should not join the usize vector items with &str type. You need to convert usize to string first then join it:
map(|u| u.to_string())
The standard library's join is defined only for slices, so the following code works:
let books: &[_] = &["1", "2", "3"];
let n_books: usize = 2;
let result = books[0..n_books].join(" ");
println!("{}", result); // "1 2"
Edit:
From your comment:
What's the difference using take(n) or a subscript operator (re-slicing books[0..n_books])
A slice is a type composed of a length and a pointer to a memory.
You may use .take(n_books) instead of re-slicing, which is an iterator that only iterates over the first n iterations of iter, try this:
let books: Vec<usize> = vec![1, 2, 3];
let n_books: usize = 2;
let result = books
.iter()
.take(n_books)
.map(|u| u.to_string())
.collect::<Vec<_>>()
.join(" ");
println!("{}", result); //"1 2"