记一起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();
}

 

posted @ 2024-02-01 13:15  ALXPS  阅读(10)  评论(0编辑  收藏  举报