2014-03-15 9 views
3

В следующем примере:Finding слово в предложении

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) 

Что такое правильный способ найти слово в предложении?

ответ

2
let sentence = "Lorem ipsum dolor sit amet"; 
if sentence.words().any(|x| x == "ipsum") { 
    println!("Found it!"); 
} 

Вы также могли бы сделать что-то с .position() или .count() вместо .any(). См. Iterator trait.

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 находится в середине изменения языка, называемого dynamically-sized types (DST). Одним из побочных эффектов является то, что смысл выражения &"string" и &[element1, element2], где & появляется перед строкой или массивом буквального, будет меняться (T тип элементов массива element1 и element2):

  1. Старое поведение (по-прежнему текущее как Rust 0.9): выражения &"string" и &[element1, element2] принуждаются к срезам &str и &[T] соответственно. Склоны относятся к диапазонам неизвестной длины базовой строки или массива.

  2. Новое поведение: Выражения &"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!"); 
    } 
} 
+1

Это не связано с DST - это просто почему-то непонятно для меня было решено, что '&" lorem "' будет эквивалентно '' lorem'', к лучшему или к худшему. Вам просто нужно обратиться к этому: '& &" lorem "' (не '&&" lorem "', потому что '&&' будет обрабатываться как двоичный и оператор). –

+0

С последней версией Rust (14-Mar-2014) вышеупомянутое решение не компилируется - ошибка «заимствованное значение не достаточно долгое время». @ Альтернативные работы ChrisMorgan. – quux00

+0

'& (" lorem ")' работает тоже. – huon

Смежные вопросы