在 Rust 中引用和取消引用数据库连接

Referencing and dereferencing a db connection in rust

我的问题是关于 取消引用引用 在 rust 中。

我有以下代码:

#[database("pg_db")]
struct PgDbConn(diesel::PgConnection);

fn main() {
    rocket::ignite()
        .attach(PgDbConn::fairing())
        .mount("/", routes![find_one, find_all])
        .launch();
}

#[get("/<id>", format = "json")]
fn find_one(conn: PgDbConn, id: i32) -> Result<Json<Person>, NotFound<String>> {
    let one: QueryResult<Person> = person.find(id).first(&*conn); // Notice here deref & ref
    ...

我想知道我的 PgDbConn 结构是如何作为连接结束的。有人可以详细解释一下这个机制吗?

我们来看看(部分)the implementation of the database attribute macro:

Ok(quote! {
    //...
    impl ::std::ops::Deref for #guard_type {
        type Target = #conn_type;

        #[inline(always)]
        fn deref(&self) -> &Self::Target {
            &self.0
        }
    }

    impl ::std::ops::DerefMut for #guard_type {
        #[inline(always)]
        fn deref_mut(&mut self) -> &mut Self::Target {
            &mut self.0
        }
    }
})

#guard_type 在您的示例中是 PgDbConn 并且 #conn_typediesel::PgConnection,因此生成的代码如下所示:

impl ::std::ops::Deref for PgDbConn {
    type Target = diesel::PgConnection;

    #[inline(always)]
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl ::std::ops::DerefMut for PgDbConn {
    #[inline(always)]
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

使用 DerefDerefMut,您可以为自己的类型实现取消引用,在本例中为 PgDbConn。现在,你可以写 *conn 从你的 PgDbConn 得到一个 diesel::PgConnection。但是,您想要 referencediesel::PgConnection。要获得引用,您必须再次引用取消引用的 PgDbConn,因此最终结果是 &*conn.