Issue
So I wrote this recursive string join function in Rust which seems to work, but I'm a bit confused why it works.
fn join(separator: &str, strs: &[&str]) -> String {
match strs.len() {
l if l > 1 => return strs[0].to_string() + separator + &join(separator, &strs[1..]),
l if l == 1 => return strs[0].to_string(),
_ => return "".to_string(),
}
}
So I have an array of 3 Strings that I would like to join and a String separator. The function takes in the reference to a str &str for its first argument and then a reference to an array of Strings &[&str] for the second argument.
let j1 = ["one", "two", "three"];
println!("{}", join(", ", &j1));
- Why does the recursive join have to be defined as
&join(separator, &strs[1..])? - why does
&strs[1..]have to be dereferenced again?
Solution
std::ops::Add<&'_ str>is implemented forString(scroll to the very bottom of the page).std::ops::Add<String>is not. Hence, you can only add&'_ strs toStrings, and only on the right hand side. You have to reference your call tojoinbecause that uses deref coercion to turn theStringinto a&str.This one is a bit more convoluted to provide exact evidence for, but in simplest terms, slicing (using a range in the index position) a slice or array will produce a slice, IE,
[T]. Since you can't pass around bare[T]s around, you need to take a reference to it.
The more exact reason as to why is:Index<i>is impl-ed for[T]whereI: SliceIndex<[T]>.- The output is
I's output as aSliceIndex. 1..is a[std::ops::RangeFrom](https://doc.rust-lang.org/beta/std/ops/struct.RangeFrom.html).SliceIndex<[T]>is impl-ed for all[T]onRangeFrom<usize>.- The output is
[T]and not&[T].
Additionally, this isn't the most idiomatic way of writing this function:
pub fn join(separator: &str, strs: &[&str]) -> String {
match strs {
[last] => last.to_string(),
[current, rest @ ..] => current.to_string() + separator + &join(separator, &rest),
[] => "".to_string(),
}
}
Pattern matching works on slices.
Answered By - Optimistic Peach Answer Checked By - Clifford M. (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.