Hi, everyone. I'm facing this problem and I can't understand how it can be solved without using 'static or clone everything.
use std::time::Duration;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
struct DataMessage {
field1: u32,
field2: String,
}
#[derive(Debug, serde::Serialize, serde::Deserialize)]
struct DataMessage2 {
field1: i32,
field2: Vec<u8>,
}
async fn heavy_compute<DataMessageType: serde::Serialize + Send>(
data_message: DataMessageType,
handler_data: &[u8],
) -> anyhow::Result<String> {
tokio::task::spawn_blocking(move || {
std::thread::sleep(Duration::from_secs(1));
let buf = serde_json::to_vec(&data_message)?;
let len1 = buf.len();
let len2 = handler_data.len();
Ok(format!("result {} {}", len1, len2).to_string())
})
.await?
}
struct Handler {
handler_data: Vec<u8>,
}
impl Handler {
pub fn new(data: &[u8]) -> Self {
Handler {
handler_data: data.to_vec(),
}
}
pub async fn compute<DataMessageType: serde::Serialize + Send>(
&self,
data_message: DataMessageType,
) -> anyhow::Result<String> {
let res = heavy_compute(data_message, self.handler_data.as_slice()).await?;
Ok(res)
}
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let handler = Handler::new(&[1, 1, 1, 1]);
let data_message1 = DataMessage {
field1: 1,
field2: "wow".to_string(),
};
let data_message2 = DataMessage2 {
field1: 2,
field2: vec![2, 2, 2, 2],
};
let res1 = handler.compute(data_message1).await?;
println!("res1 {}", res1);
let res2 = handler.compute(data_message2).await?;
println!("res2 {}", res2);
Ok(())
}
compiler output:
error[E0310]: the parameter type `DataMessageType` may not live long enough
--> src\main.rs:41:5
|
41 | / tokio::task::spawn_blocking(move || {
42 | | std::thread::sleep(Duration::from_secs(1));
43 | |
44 | | let buf = serde_json::to_vec(&data_message)?;
... |
48 | | Ok(format!("result {} {}", len1, len2).to_string())
49 | | })
| |______^ ...so that the type `DataMessageType` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
37 | async fn heavy_compute<DataMessageType: serde::Serialize + Send + 'static>(
| +++++++++
error[E0311]: the parameter type `DataMessageType` may not live long enough
--> src\main.rs:41:5
|
41 | / tokio::task::spawn_blocking(move || {
42 | | std::thread::sleep(Duration::from_secs(1));
43 | |
44 | | let buf = serde_json::to_vec(&data_message)?;
... |
48 | | Ok(format!("result {} {}", len1, len2).to_string())
49 | | })
| |______^
|
note: the parameter type `DataMessageType` must be valid for the anonymous lifetime defined here...
--> src\main.rs:39:19
|
39 | handler_data: &[u8],
| ^^^^^
note: ...so that the type `DataMessageType` will meet its required lifetime bounds
--> src\main.rs:41:5
|
41 | / tokio::task::spawn_blocking(move || {
42 | | std::thread::sleep(Duration::from_secs(1));
43 | |
44 | | let buf = serde_json::to_vec(&data_message)?;
... |
48 | | Ok(format!("result {} {}", len1, len2).to_string())
49 | | })
| |______^
help: consider adding an explicit lifetime bound...
|
37 ~ async fn heavy_compute<'a, DataMessageType: serde::Serialize + Send + 'a>(
38 | data_message: DataMessageType,
39 ~ handler_data: &'a [u8],
|
error[E0521]: borrowed data escapes outside of function
--> src\main.rs:41:5
|
39 | handler_data: &[u8],
| ------------ - let's call the lifetime of this reference `'1`
| |
| `handler_data` is a reference that is only valid in the function body
40 | ) -> anyhow::Result<String> {
41 | / tokio::task::spawn_blocking(move || {
42 | | std::thread::sleep(Duration::from_secs(1));
43 | |
44 | | let buf = serde_json::to_vec(&data_message)?;
... |
48 | | Ok(format!("result {} {}", len1, len2).to_string())
49 | | })
| | ^
| | |
| |______`handler_data` escapes the function body here
| argument requires that `'1` must outlive `'static`
Some errors have detailed explanations: E0310, E0311, E0521.
For more information about an error, try `rustc --explain E0310`.