0

我的问题是关于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结构如何最终成为连接。有人可以详细解释一下机制吗?

4

1 回答 1

2

让我们看一下属性宏的(部分)实现database

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_typeisPgDbConn#conn_typeisdiesel::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
    }
}

使用Derefand DerefMut,您可以为自己的类型实现取消引用,在这种情况下PgDbConn*conn现在,您可以写信diesel::PgConnection从您的PgDbConn. 但是,您需要参考. diesel::PgConnection要获得引用,您必须再次引用取消引用的PgDbConn,因此最终结果是&*conn.

于 2021-08-04T09:06:53.257 回答