在以下示例中:
fn main() {
let str_vec: ~[&str] = "lorem lpsum".split(' ').collect();
if (str_vec.contains("lorem")) {
println!("found it!");
}
}
它不会编译,并说:
error: mismatched types: expected &&'static str
but found 'static str (expected &-ptr but found &'static str)
在句子中找到单词的正确方法是什么?
答案 0 :(得分:4)
向量上的contains()
方法(具体地说,在满足std::vec::ImmutableEqVector
特征的所有向量上,对于包含可以进行相等比较的类型的所有向量),具有以下签名,
fn contains(&self, x: &T) -> bool
其中T
是数组中元素的类型。在您的代码中,str_vec
包含&str
类型的元素,因此您需要传入&&str
- 即借用指向&str
的指针。
由于"lorem"
的类型为&'static str
,您可能首先尝试编写
str_vec.contains(&"lorem")`
在当前版本的Rust中,这不起作用。 Rust正处于语言变化的中间,称为dynamically-sized types (DST)。其中一个副作用是表达式&"string"
和&[element1, element2]
的含义,其中&
出现在字符串或数组文字之前,将会改变(T
是类型数组元素element1
和element2
):
旧行为(从Rust 0.9开始仍然是最新的):表达式&"string"
和&[element1, element2]
分别被强制转换为切片&str
和&[T]
。切片指的是底层字符串或数组的未知长度范围。
新行为:表达式&"string"
和&[element1, element2]
被解释为& &'static str
和&[T, ..2]
,使其解释与Rust的其余部分一致。
在这些制度中的任何一种,获得一个静态大小的字符串或数组的最惯用的方法是使用.as_slice()
方法。获得切片后,只需借用指向该切片的指针即可获得&&str
所需的.contains()
类型。最终代码如下(if
条件不需要在Rust中用括号括起来,如果你有不必要的括号,rustc会发出警告):
fn main() {
let str_vec: ~[&str] = "lorem lpsum".split(' ').collect();
if str_vec.contains(&"lorem".as_slice()) {
println!("found it!");
}
}
编译并运行以获取:
found it!
修改最近,一项更改已落地,以~[T]
开始发出警告,该广告已被弃用,支持Vec<T>
类型,该类型也是拥有的向量,但没有特殊的语法。 (目前,您需要从std::vec_ng
库中导入该类型,但我相信模块std::vec_ng
最终将通过替换当前std::vec
而消失。)一旦做出此更改,似乎你不能借用"lorem".as_slice()
的引用,因为rustc认为生命周期太短 - 我认为这也是一个错误。在当前的master上,我上面的代码应该是:
use std::vec_ng::Vec; // Import will not be needed in the future
fn main() {
let str_vec: Vec<&str> = "lorem lpsum".split(' ').collect();
let slice = &"lorem".as_slice();
if str_vec.contains(slice) {
println!("found it!");
}
}
答案 1 :(得分:2)
let sentence = "Lorem ipsum dolor sit amet";
if sentence.words().any(|x| x == "ipsum") {
println!("Found it!");
}
您也可以使用.position()
或.count()
代替.any()
执行某些操作。请参阅Iterator trait。