Hi all. My current understanding of lifetimes does not understand why I am getting some compiler errors with this piece of code:
enum Inflection {
Question_NoYelling,
Question_Yelling,
Yelling_NoQuestion,
Other,
}
fn is_whitespace_or_question_mark(c: char) -> bool {
match c {
' ' => true,
'?' => true,
'\t' => true,
'\n' => true,
_ => false,
}
}
fn split_message_into_words_and_punctuation<'a>(message: &'a str) -> Vec<&'a str> {
String::from(message).split(is_whitespace_or_question_mark)
.filter(|element| element.len() != 0).collect()
}
fn is_uppercase(word: &str) -> bool {
if word != "?" && word == &word.to_string().to_uppercase() {
true
} else {
false
}
}
fn get_inflection(message: &str) -> Inflection {
let mut is_question: bool = false;
let mut is_yelling: bool = false;
let words_and_punctuation: Vec<&str> = split_message_into_words_and_punctuation(message);
for element in words_and_punctuation.iter() {
if is_uppercase(element) {
is_yelling = true;
break;
}
}
if words_and_punctuation[words_and_punctuation.len() - 1] == "?" {
is_question = true;
}
match (is_question, is_yelling) {
(true, true) => Inflection::Question_Yelling,
(true, false) => Inflection::Question_NoYelling,
(false, true) => Inflection::Yelling_NoQuestion,
(false, false) => Inflection::Other,
}
}
fn reply_to_non_empty(message: &str) -> &str {
match get_inflection(message) {
Inflection::Question_NoYelling => "Sure.",
Inflection::Question_Yelling => "Whoa, chill out!",
Inflection::Yelling_NoQuestion => "Calm down, I know what I'm doing!",
Inflection::Other => "Whatever.",
}
}
pub fn reply(message: &str) -> &str {
let message: &str = String::from(message).trim();
match message {
"" => "Fine. Be that way!",
_ => reply_to_non_empty(message),
}
}
The first error I am getting:
error[E0597]: borrowed value does not live long enough
--> src\lib.rs:19:5
|
19 | String::from(message).split(is_whitespace_or_question_mark)
| ^^^^^^^^^^^^^^^^^^^^^ does not live long enough
...
22 | }
| - temporary value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 18:1...
--> src\lib.rs:18:1
|
18 | / fn split_message_into_words_and_punctuation<'a>(message: &'a str) -> Vec<&'a str> {
19 | | String::from(message).split(is_whitespace_or_question_mark)
20 | | .filter(|element| element.len() != 0).collect()
21 | |
22 | | }
| |_^
This is complaining about the function split_message_into_words_and_punctuation
, which returns the result of a collect
on an iterator. A similar complaint is made about what is returned from calling trim
:
pub fn reply(message: &str) -> &str {
let message: &str = String::from(message).trim();
match message {
"" => "Fine. Be that way!",
_ => reply_to_non_empty(message),
}
}
I have worked through basic examples on lifetime, and I think I get the concept, but I am having trouble understanding why manipulations on the String::from
have trouble living long enough when I am returning string literals, which are basically like constants?