contains()
метод на векторы (в частности, на всех векторов, удовлетворяющих std::vec::ImmutableEqVector
черта, которая является для всех векторов, содержащих типы, которые можно сравнить на равенство), имеет следующую подпись,
fn contains(&self, x: &T) -> bool
где T
находится тип элемента в массиве. В вашем коде str_vec
содержит элементы типа &str
, поэтому вам необходимо передать в &&str
- то есть заимствованный указатель на &str
.
Поскольку тип "lorem"
является &'static str
, вы можете попытаться сначала просто написать
str_vec.contains(&"lorem")`
В текущей версии Руст, который не работает. 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
не должны быть заключены в круглые скобки в ржавчине, и rustc будет предупреждать, если у вас есть лишние скобки):
fn main() {
let str_vec: ~[&str] = "lorem lpsum".split(' ').collect();
if str_vec.contains(&"lorem".as_slice()) {
println!("found it!");
}
}
откомпилировать и запустить, чтобы получить:
found it!
Edit: Недавно изменение приземлился начать предупреждение о ~[T]
, который является устаревшим в пользу типа Vec<T>
, который также является собственным вектор, но не ч ave специальный синтаксис.(На данный момент вам нужно импортировать этот тип из библиотеки std::vec_ng
, но я считаю, что модуль std::vec_ng
уйдет в конце концов, заменив текущий std::vec
.) Как только это изменение будет сделано, кажется, что вы не можете взять ссылку на "lorem".as_slice()
потому что rustc считает жизнь слишком коротким - я думаю, что это тоже ошибка. На текущий мастер, мой код выше должен быть:
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!");
}
}
Это не связано с DST - это просто почему-то непонятно для меня было решено, что '&" lorem "' будет эквивалентно '' lorem'', к лучшему или к худшему. Вам просто нужно обратиться к этому: '& &" lorem "' (не '&&" lorem "', потому что '&&' будет обрабатываться как двоичный и оператор). –
С последней версией Rust (14-Mar-2014) вышеупомянутое решение не компилируется - ошибка «заимствованное значение не достаточно долгое время». @ Альтернативные работы ChrisMorgan. – quux00
'& (" lorem ")' работает тоже. – huon