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&'_ str
s toString
s, and only on the right hand side. You have to reference your call tojoin
because that uses deref coercion to turn theString
into 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.