Consider the following 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(message: &str) -> Vec<&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 compiler complains about two locations:
pub fn reply(message: &str) -> &str {
let message: &str = String::from(message).trim();
match message {
"" => "Fine. Be that way!",
_ => reply_to_non_empty(message),
}
}
and
fn split_message_into_words_and_punctuation(message: &str) -> Vec<&str> {
String::from(message).split(is_whitespace_or_question_mark)
.filter(|element| element.len() != 0).collect();
}
In both cases, the compiler says that String::from(message)
does not live long enough. But, why does it matter if String::from(message)
doesn't live long enough, when I am only using it to get either a string literal, or a Vec
of string literals in the end?
For reference, an example of the compiler's complaint:
error[E0597]: borrowed value does not live long enough
--> src\lib.rs:69:25
|
69 | let message: &str = String::from(message).trim();
| ^^^^^^^^^^^^^^^^^^^^^ - temporary value only lives until here
| |
| does not live long enough
|
|
note: borrowed value must be valid for the anonymous lifetime #1 defined on the function body at 68:1...
--> src\lib.rs:68:1
|
68 | / pub fn reply(message: &str) -> &str {
69 | | let message: &str = String::from(message).trim();
70 | |
71 | | match message {
... |
74 | | }
75 | | }
| |_^