[英]How does this recursive join work in Rust
So I wrote this recursive string join function in Rust which seems to work, but I'm a bit confused why it works.所以我在 Rust 中写了这个递归字符串 join function ,这似乎有效,但我有点困惑为什么它有效。
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.所以我有一个要加入的 3 个字符串数组和一个字符串分隔符。 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. function 的第一个参数引用一个 str
&str
,第二个参数引用一个字符串数组&[&str]
。
let j1 = ["one", "two", "three"];
println!("{}", join(", ", &j1));
&join(separator, &strs[1..])
?&join(separator, &strs[1..])
?&strs[1..]
have to be dereferenced again?&strs[1..]
必须再次取消引用?std::ops::Add<&'_ str>
is implemented for String
(scroll to the very bottom of the page). std::ops::Add<&'_ str>
是为String
实现的(滚动到页面的最底部)。 std::ops::Add<String>
is not. std::ops::Add<String>
不是。 Hence, you can only add &'_ str
s to String
s, and only on the right hand side.因此,您只能将
&'_ str
s 添加到String
s,并且只能在右侧。 You have to reference your call to join
because that uses deref coercion to turn the String
into a &str
.您必须引用您的
join
电话,因为它使用 deref 强制将String
转换为&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]
.这有点复杂,无法提供确切的证据,但用最简单的术语来说,切片(使用索引位置中的范围)切片或数组将产生切片,IE,
[T]
。 Since you can't pass around bare [T]
s around, you need to take a reference to it.由于您无法传递裸露的
[T]
,因此您需要对其进行引用。
The more exact reason as to why is:更确切的原因是:
Index<i>
is impl-ed for [T]
where I: SliceIndex<[T]>
. Index<i>
是为[T]
实现的,其中I: SliceIndex<[T]>
。I
's output as a SliceIndex
. I
的 output 作为SliceIndex
。1..
is a [std::ops::RangeFrom](https://doc.rust-lang.org/beta/std/ops/struct.RangeFrom.html)
. 1..
是[std::ops::RangeFrom](https://doc.rust-lang.org/beta/std/ops/struct.RangeFrom.html)
。SliceIndex<[T]>
is impl-ed for all [T]
on RangeFrom<usize>
. SliceIndex<[T]>
是对RangeFrom<usize>
上的所有[T]
实现的。[T]
and not &[T]
. [T]
而不是&[T]
。 Additionally, this isn't the most idiomatic way of writing this function:此外,这不是编写此 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(),
}
}
&join(separator, &strs[1..])
?&join(separator, &strs[1..])
?
+
operator is syntactic sugar for std::ops::Add
. +
运算符是std::ops::Add
的语法糖。String
has only one Add
implementation , impl<'_> Add<&'_ str> for String
, which means you can do String + &str
but not String + String
. String
只有一个Add
实现, impl<'_> Add<&'_ str> for String
,这意味着你可以做String + &str
但不能做String + String
。join
returns a String
, you have to get a &str
from the result with &join(...)
in order to use the +
operator.join
返回一个String
,您必须使用&join(...)
从结果中获取一个&str
才能使用+
运算符。&strs[1..]
have to be dereferenced again?&strs[1..]
必须再次取消引用? (I'm assuming you mean, "why can't I just write strs[1..]
?") strs[1..]
?”)
strs[1..]
means "the sequence of values contained by strs
from index 1 to the end".strs[1..]
表示“ strs
包含的从索引 1 到末尾的值序列”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.