I want to create a String from the part of the vector.
My code:
fn main() {
let v = vec!['a', 'b', 'c', 'd'];
let mut res = String::new(); // expect to have "cd"
let start_pos: usize = 2;
for i in start_pos..v.len() {
res.push(v[i]);
}
println!("{}", res); // "cd"
}
Is it possible to do the same shorter?
-
5\$\begingroup\$ This isn't Code Golf, so we prefer "better" to "shorter" (sometimes shorter is better, sometimes not). \$\endgroup\$Toby Speight– Toby Speight2023年10月21日 09:07:17 +00:00Commented Oct 21, 2023 at 9:07
1 Answer 1
You could convert the Vec
into an iterator, and write this in fluent style.
fn main() {
let v = vec!['a', 'b', 'c', 'd'];
let res : String = v
.into_iter()
.skip(2)
.collect();
println!("{}", res); // "cd"
}
Instead of skip(2)
on the iterator, you could convert a slice of the Vec
:
fn main() {
let v = vec!['a', 'b', 'c', 'd'];
let res : String = v[2..]
.into_iter()
.collect();
println!("{}", res); // "cd"
}
I find this very readable, and it generates fast code. One advantage it has is that res
no longer needs to be mut
, but can be a static single assignment. To achieve that with the loop implementation, you would need to move the loop into a helper, or "phi," function.
In real-world code, a container like v
, whose data are compile-time constants and never modified, would be a const
or static
array, not a Vec
.
Recall that a Rust String
holds UTF-8 bytes, not an array of UCS-4 char
. There’s a function to move a Vec<u8>
that holds valid UTF-8 bytes into a String
: String::from_utf8
. It’s likely that your input will be in UTF-8 as well, so if you can avoid the overhead of converting between UCS-4 and UTF-8 or vice versa, that will be far more efficient.