I think the problem I'm running into with this code is that the struct I'm trying to return has variables that are strings. Currently I am querying an InfluxDB database and storing the result in the result
variable. The print line towards the bottom of my function confirms that the index it correctly and is printing
IotData { time: 2021-12-27T14:01:34.404593Z, device_id: "1000", transaction_date: "27-12-2021", transaction_time: "14:01:34", usage: 8 }
How do I return this struct? I added the Clone
attribute to the struct and return the clone since I encountered the has not attribute 'Copy'
error, but now I am receiving the error, use of moved value: 'result'
. I am new to Rust and don't quite understand ownership. My next guess is that I need to add lifetimes to my function and return the reference instead, but am not sure where to go from here.
Code Dump:
use influxdb::{ Client, ReadQuery};
use chrono::{ Utc };
extern crate serde;
extern crate serde_json;
use serde_derive::{ Serialize, Deserialize };
#[derive(Serialize, Deserialize, Debug, Clone)]
struct IotData {
time: chrono::DateTime<Utc>,
device_id: String,
transaction_date: String,
transaction_time: String,
usage: i64,
}
pub async fn pull(last_time: u64) -> IotData {
let client = Client::new("http://localhost:8086", "PuPPY");
let query_text = format!("
SELECT *
FROM device_data
WHERE time > {}
ORDER BY time
LIMIT 1", last_time);
let read_query = ReadQuery::new(query_text);
let result = client
.json_query(read_query)
.await
.and_then(|mut db_result| db_result.deserialize_next::<IotData>());
println!("{:?}", result.unwrap().series[0].values[0]);
return result.unwrap().series[0].values[0].clone();
}
Minimized example yielding the essentially same error:
pub fn pull<T: std::fmt::Debug>(opt: Option<T>) -> T {
println!("{:?}", opt.unwrap());
opt.unwrap()
}
Playground
The error is this:
error[E0382]: use of moved value: `opt`
--> src/lib.rs:3:5
|
1 | pub fn pull<T: std::fmt::Debug>(opt: Option<T>) -> T {
| --- move occurs because `opt` has type `Option<T>`, which does not implement the `Copy` trait
2 | println!("{:?}", opt.unwrap());
| -------- `opt` moved due to this method call
3 | opt.unwrap()
| ^^^ value used here after move
|
note: this function takes ownership of the receiver `self`, which moves `opt`
help: consider calling `.as_ref()` to borrow the type's contents
|
2 | println!("{:?}", opt.as_ref().unwrap());
| +++++++++
(By the way, if you're reading your errors from IDE, you might not see most of this. That's the general advice: confusing compiler errors in IDE are usually more clear in console, where they are not trimmed)
Here, it's easy to see the issue: Option::unwrap
consumes self
, since that's the only way for it to yield the owned value. So, then we unwrap the incoming Option
to print its contents, we destroy it for good - there's nothing more to return.
To fix it, we can do one of the following:
as_ref
before first unwrap
. In this case, we will consume not the Option<T>
, but only the shared reference to it, which can be freely used without touching the value.println!
, since it seems to be purely debugging information anyway. Option
once, and then use the unwrapped value twice:pub async fn pull(last_time: u64) -> IotData {
// --snip--
let value = result.unwrap().series[0].values[0];
println!("{:?}", value);
return value;
}
Note also that you don't really need clone
in any case - again, Option::unwrap
returns an owned value, so you don't have to clone it explicitly.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.