我正在尝试反转给定字符串中的单词。例如-“John is amazing”将返回“amazing is John”。下面的代码片段可以工作:
pub fn reverse_words1(input: &str) -> String {
let words: Vec<&str> = input.split(" ").collect();
let mut reversed: Vec<&str> = Vec::new();
for w in words.iter().rev() {
reversed.push(w);
}
reversed.join(" ")
}
但是,以下方法行不通:
pub fn reverse_words2(input: &str) -> String {
let words: Vec<&str> = input.split(" ").collect();
// Error here 👇
let reversed: Vec<&str> = words.iter().rev().collect();
reversed.join(" ")
}
错误是:
a value of type `Vec<&str>` cannot be built from an iterator over elements of type `&&str`.
我这里有三个问题:
1.为什么迭代器提供对&str
的引用,而不是直接访问&str
,因为它已经是对字符串的切片/引用?
1.为什么第一个函数起作用而第二个函数不起作用?
1.函数的返回类型是String
,而我试图联接Vec<&str>
。难道join
不应该导致&str
而不是String
类型吗?铁 rust 是否做价值的自动转换?
最后,如何修复第二个函数,以便不必维护自己的for
结构?
2条答案
按热度按时间2uluyalo1#
正如Alexey所解释的,
Vec<T>::iter
生成一个项类型为&T
的迭代器。因为你有一个Vec<&str>
,这意味着它产生的迭代器具有&&str
类型。你可以通过使用
into_iter
来解决这个问题:但最好避免在一开始就直接从反向迭代器中收集来创建向量:
fafcakar2#
当你传递一个值给一个函数时,如果需要的话,它会自动被取消引用。在for循环中:
w
的类型为&&str
,它会自动解引用到&str
中,以匹配push
所需的类型。您可以通过添加
copied
来修复第二个。对于为什么得到
String
而不是&str
,这是因为join
的返回取决于项目的类型和分隔符的类型。在
Join
的文档中,有一个[&str]
和分隔符&str
的实现,以输出String
。Borrow<str>
是另一个trait,但这里唯一相关的是&str
实现了Borrow<str>
。Join
trait已经这样实现了,因为它需要一个可变的、可增长的类型来放入数据。它不能返回&str
,因为它可以访问的(在切片中)是不可变的,而且因为它是一个引用,它不能创建一个新的引用,因为这需要函数外部的东西来拥有它。String
解决了这些问题。请注意,当您提供
char
到split
而不是&str
时,您可以反向迭代它,因此实际上不需要中间的Vec
。然后你可以直接收集到一个
String
。如果你需要一个非空的分隔符,你可以做一些迭代器体操。