【问题标题】:Referencing and dereferencing a db connection in rust在 rust 中引用和取消引用数据库连接
【发布时间】:2021-10-09 08:05:04
【问题描述】:

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

【问题讨论】:

    标签: rust rust-diesel rocket


    【解决方案1】:

    让我们看看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。但是,您需要对diesel::PgConnection引用。要获得引用,您必须再次引用取消引用的PgDbConn,因此最终结果是&amp;*conn

    【讨论】:

    • 非常感谢您提供详细而相关的答案!
    • 在火箭方面更好的解决方案是直接在#guard_type 上实现diesel::Connection,这样用户就不必进行&amp;*conn deref 转换。这似乎是一个很常见的混淆来源。为此,在他们的错误跟踪器中填写一个问题可能是有意义的。
    猜你喜欢
    • 1970-01-01
    • 2020-09-17
    • 2016-09-28
    • 2019-02-28
    • 2018-07-14
    • 1970-01-01
    • 2018-08-08
    • 2022-12-20
    • 2018-10-12
    相关资源
    最近更新 更多