记一起rust悬垂引用解决
最初要写一段从redis的hash获取json字符串,转化为结构体,代码逻辑如下
use redis::{Client, Commands, Connection, Iter};
use serde::{Deserialize, Serialize};
const HASH_KEY: &str = "rust_test_hash_key";
#[derive(Serialize, Deserialize, Debug)]
struct A<'a> {
id: &'a str,
}
struct Logic {
redis: Client,
}
impl Logic {
fn new() -> Self {
let redis_client =
Client::open("redis://@127.0.0.1:6378/10").unwrap();
Logic {
redis: redis_client,
}
}
fn get_redis_conn(&self) -> Connection {
self.redis.get_connection().unwrap()
}
fn store_as(&self) {
let mut conn = self.get_redis_conn();
let field = "field_name";
let a = A { id: "id0" };
let value = serde_json::to_string(&a).unwrap();
let _: () = conn.hset(HASH_KEY, field, value).unwrap();
}
fn load_as(&self) -> Vec<A> {
let mut conn = self.get_redis_conn();
let results: Iter<(String, String)> = conn.hscan(HASH_KEY).unwrap();
let mut vs = Vec::new();
for (_k, v) in results {
let a: A = serde_json::from_str(&v).unwrap();
vs.push(a);
}
vs
}
fn clear_as(&self) {
let mut conn = self.get_redis_conn();
let _: () = conn.del(HASH_KEY).unwrap();
}
}
fn main() {
let logic = Logic::new();
logic.store_as();
let a_s = logic.load_as();
println!("a_s is {:?}", a_s);
logic.clear_as();
}
结果运行报错如下
error[E0515]: cannot return value referencing local variable `v`
--> src/main.rs:2051:9
|
2048 | let a: A = serde_json::from_str(&v).unwrap();
| -- `v` is borrowed here
...
2051 | vs
| ^^ returns a value referencing data owned by the current function
很明显是悬垂引用问题
修改后的代码如下
use redis::{Client, Commands, Connection, Iter};
use serde::{Deserialize, Serialize};
const HASH_KEY: &str = "rust_test_hash_key";
#[derive(Serialize, Deserialize, Debug)]
struct A<'a> {
id: &'a str,
}
struct Logic {
redis: Client,
}
impl Logic {
fn new() -> Self {
let redis_client =
Client::open("redis://@127.0.0.1:6378/10").unwrap();
Logic {
redis: redis_client,
}
}
fn get_redis_conn(&self) -> Connection {
self.redis.get_connection().unwrap()
}
fn store_as(&self) {
let mut conn = self.get_redis_conn();
let field = "field_name";
let a = A { id: "id0" };
let value = serde_json::to_string(&a).unwrap();
let _: () = conn.hset(HASH_KEY, field, value).unwrap();
}
fn load_a_strs(&self) -> Vec<String> {
let mut conn = self.get_redis_conn();
let results: Iter<(String, String)> = conn.hscan(HASH_KEY).unwrap();
let mut vs = Vec::new();
for (_k, v) in results {
vs.push(v);
}
vs
}
fn strs_as(a_strs: &Vec<String>) -> Vec<A> {
let mut a_s = Vec::with_capacity(a_strs.len());
for b in a_strs {
let a: A = serde_json::from_str(b).unwrap();
a_s.push(a);
}
a_s
}
fn clear_as(&self) {
let mut conn = self.get_redis_conn();
let _: () = conn.del(HASH_KEY).unwrap();
}
}
fn main() {
let logic = Logic::new();
logic.store_as();
let b_s = logic.load_a_strs();
let a_s = Logic::strs_as(&b_s);
println!("a_s is {:?}", a_s);
logic.clear_as();
}