I've been trying to write a very small routine that gets data from the database and passes into a function, but can't really grasp the concept of borrow in here. The compiler refuses to compile the following code:
use std::thread::sleep;
use std::time::Duration;
use std::process::Command;
use std::process::Child;
use std::collections::HashMap;
use tokio_postgres::{NoTls, Error};
type AgentMap = HashMap<String, Child>;
fn spawn<S: AsRef<str>>(name: S) -> Child {
Command::new("python")
.arg("worker.py")
.arg(name.as_ref())
.spawn()
.expect("worker failed to start")
}
#[tokio::main]
async fn main() -> Result<(), Error> {
let (client, connection) = tokio_postgres::connect("host=localhost port=5432 user=pg password=pg dbname=test", NoTls).await?;
tokio::spawn(async move {
if let Err(e) = connection.await {
eprintln!("connection error: {}", e);
}
});
let mut agents = AgentMap::new();
let rows = client
.query("select id, user_id, cat_id created_at from my_table", &[])
.await?;
for row in rows {
let id: i32 = row.get("id");
let uid: i32 = row.get("user_id");
let cid: i32 = row.get("cat_id");
let name: &str = format!("line:{}:{}:{}", id, uid, cid).as_str();
if agents.contains_key(name) {
continue;
}
agents.insert(name.to_string(), spawn(name));
}
Ok(())
}
Errors:
Compiling playground v0.0.1 (/playground)
warning: unused import: `std::thread::sleep`
--> src/main.rs:1:5
|
1 | use std::thread::sleep;
| ^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: unused import: `std::time::Duration`
--> src/main.rs:2:5
|
2 | use std::time::Duration;
| ^^^^^^^^^^^^^^^^^^^
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:37:26
|
37 | let name: &str = format!("line:{}:{}:{}", id, uid, cid).as_str();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary value which is freed while still in use
38 |
39 | if agents.contains_key(name) {
| ---- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0716`.
warning: `playground` (bin "playground") generated 2 warnings
error: could not compile `playground` (bin "playground") due to previous error; 2 warnings emitted
What is wrong, though? I'm keeping everything as a &str to avoid allocating a big String and then just sending that to the HashMap.