Hello. I got some pretty simple code...
#[derive(Debug)]
struct StatsdMessage<'a> {
kind: &'a str,
metric: &'a str,
value: u64,
tags: Option<Vec<&'a str>>,
sample_rate: Option<f64>
}
#[tokio::main]
async fn main() {
let (tx, mut rx) = tokio::sync::mpsc::channel(10);
let tx1 = tx.clone();
tokio::spawn(async move {
let msg = StatsdMessage{
kind: "count",
value: 456,
metric: "bar",
tags: Some(vec!["blah:test"]),
sample_rate: None
};
tx1.send(msg).await.unwrap();
});
while let Some(msg) = rx.recv().await {
println!("{:?}", msg);
}
}
Works as expected. But when I try to factor the body of the anonymous function out to a named function, I'm struggling with getting the types correct:
let tx1 = tx.clone();
tokio::spawn(async move {
send_message(tx1).await.unwrap();
});
async fn send_message(tx: tokio::sync::mpsc::Sender<StatsdMessage>) {
let msg = StatsdMessage{
kind: "histogram",
value: 123,
metric: "foo",
tags: Some(vec!["blah:test"]),
sample_rate: None
};
tx.send(msg).await;
}
The compiler complains with this error:
error[E0726]: implicit elided lifetime not allowed here
--> src/bin/statsd.rs:36:53
|
36 | async fn send_message(tx: tokio::sync::mpsc::Sender<StatsdMessage>) {
| ^^^^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>`
I tried as the compiler said, but I'm probably just getting syntax wrong. Can I get some help?
Also have some followup questions...
- What should the return type of the named function be?
- Anonymous functions are great; the type inference is a life saver! But when they get really big, it hurts maintainability... but if you break it out into named functions, you have to deal with the tedium of getting all the types right in the function signature. In my real world code, the function signature is massive and multiline because of all these giant type specs. What do people usually do?
- Also, I'm guessing I can't send a reference to a
StatsdMessage
over the channel because the task that spawned it will go out of scope and the reference would be invalid?
Thanks for the help!