在以下示例中:
fn main() {
let str_vec: ~[&str] = "lorem lpsum".split(' ').collect();
if (str_vec.contains("lorem")) {
println!("found it!");
}
}
Run Code Online (Sandbox Code Playgroud)
它不会编译,并说:
error: mismatched types: expected &&'static str
but found 'static str (expected &-ptr but found &'static str)
Run Code Online (Sandbox Code Playgroud)
在句子中查找单词的正确方法是什么?
contains()向量上的方法(具体来说,满足特征的所有向量,std::vec::ImmutableEqVector即包含可以比较相等性的类型的所有向量)具有以下签名,
fn contains(&self, x: &T) -> bool
Run Code Online (Sandbox Code Playgroud)
其中T是数组中元素的类型。在您的代码中,str_vec保存类型为 的元素&str,因此您需要传入 a——&&str即指向 a 的借用指针&str。
由于 的类型"lorem"是&'static str,您可能首先尝试编写
str_vec.contains(&"lorem")`
Run Code Online (Sandbox Code Playgroud)
在当前版本的 Rust 中,这不起作用。Rust 正处于称为动态大小类型(DST)的语言变革之中。副作用之一是出现在字符串或数组文字之前的表达式 and 的含义将会发生变化(是&"string"数组元素and的类型):&[element1, element2]&Telement1element2
旧行为(自 Rust 0.9 起仍然有效):表达式&"string"和分别&[element1, element2]被强制转换为切片&str和&[T]。切片是指底层字符串或数组的未知长度范围。
新行为:表达式&"string"和&[element1, element2]被解释为& &'static strand &[T, ..2],使它们的解释与 Rust 的其余部分保持一致。
在这两种情况下,获取静态大小的字符串或数组的切片的最惯用方法是使用该.as_slice()方法。一旦有了切片,只需借用指向该切片的指针即可获取所需&&str的类型.contains()。最终代码如下(ifRust 中的条件不需要用括号括起来,如果确实有不必要的括号,rustc 会发出警告):
fn main() {
let str_vec: ~[&str] = "lorem lpsum".split(' ').collect();
if str_vec.contains(&"lorem".as_slice()) {
println!("found it!");
}
}
Run Code Online (Sandbox Code Playgroud)
编译运行得到:
found it!
Run Code Online (Sandbox Code Playgroud)
编辑:最近,发生了一项更改,开始对 发出警告~[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!");
}
}
Run Code Online (Sandbox Code Playgroud)