2014-09-13 2 views
5

Рассмотрим следующий примерошибка «тип этого значения должен быть известен в этом контексте» в сопоставлении с образцом

fn main() { 
    f("hello", true); 
} 

fn f(str: &str, sen: bool) { 
    let s: &str = match sen { 
     false => str, 
     true => str.chars().map(|x| x.to_lowercase()).collect().as_slice() 
    }; 
    println!("{}", s); 
} 

Я получаю эту ошибку

error: the type of this value must be known in this conntext                                        
true => str.chars().map(|x| x.to_lowercase()).collect().as_slice() 
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

Я немного запутался, разве компилятор не знает, что тип str равен &str из определения функции? Что мне здесь не хватает?

ответ

4

Ошибка расположения может быть запутанной, проблема здесь в методе collect. Он является общим для любого FromIterator, и в этом случае котик-компилятор выдает тип (какой компилятор видит, вам нужен какой-то тип X, реализующий FromIterator, который имеет метод as_slice, производящий строку &).

Вторая проблема с этим кодом, что вы пытаетесь вернуть ссылку на локальное значение (результат сбора) из оператора соответствия. Вы не можете этого сделать, потому что это значение имеет время жизни этого блока и освобождается после этого, поэтому возвращаемое значение будет недействительным.

Один рабочий раствор (но это требует преобразования & ул в строку):

fn main() { 
    f("hello", true); 
} 

fn f(str: &str, sen: bool) { 
    let s: String = match sen { 
     false => str.to_string(), 
     true => str.chars().map(|x| x.to_lowercase()).collect() 
    }; 
    println!("{}", s); 
} 

Я не знаю, что вы пытаетесь достичь, в конце концов, но взглянуть на MaybeOwned, если это будет функция возвращает срез (&str) или String.

+0

Спасибо. В результате я использовал временные переменные для хранения 'String' и привязывал s к' temp_var.as_slice() '. Не уверен, есть ли лучший способ. –

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