Just when I think I am understanding lifetimes the compiler reminds me that I know nothing.
I want to process a vector of Message
that contain data that will be deserialized and processed by the function generic in Deserialize
.
#[derive(Debug, Deserialize)]
struct Message {
body: Option<String>,
}
fn process_message(d: Option<serde_json::Value>) -> bool {
println!("process_message {:?}", d);
d.is_some() && d.unwrap().is_object()
}
fn main() -> Result<(), String> {
handle(process_message)
}
where the String
body of Message
will be deserialized into (in this case) just a serde_json::Value
. Here's handle
:
fn handle<'a,F,T>(f: F) -> Result<(), String>
where F: Fn(Option<T>) -> bool,
T: Deserialize<'a>,
{
let messages = vec![
Message { body: Some("{\"foo\":\"bar\"}".to_string()) }
];
for message in &messages {
let input = if let Some(s) = &message.body {
serde_json::from_str(&s).map_err(|e| format!("oops {:?}", e))?
} else {
None
};
if process_message(input) {
do_something(&message);
}
}
Ok(())
}
This works fine. But if I replace
if process_message(input) {
do_something(&message);
}
with the parameter for the function
if f(input) {
do_something(&message);
}
I'm told off:
error[E0597]: `messages` does not live long enough
--> src/main.rs:26:20
|
18 | fn handle<'a,F,T>(f: F) -> Result<(), String>
| -- lifetime `'a` defined here
...
26 | for message in &messages {
| ^^^^^^^^^ borrowed value does not live long enough
27 | let input = if let Some(s) = &message.body {
28 | serde_json::from_str(&s).map_err(|e| format!("oops {:?}", e))?
| ------------------------ argument requires that `messages` is borrowed for `'a`
...
48 | }
| - `messages` dropped here while still borrowed
I imagine the difference being that in the failed case the compiler has inferred the type of input
to be T
which has the 'a
bound. But I don't know why this would be a problem because nothing in the function is intended to survive beyond the scope of the function. What is still borrowing messages
at the end of the function?
Help appreciated.