在 rust 中引用和取消引用数据库连接
Posted
技术标签:
【中文标题】在 rust 中引用和取消引用数据库连接【英文标题】:Referencing and dereferencing a db connection in 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
结构是如何作为连接结束的。有人可以详细解释一下机制吗?
【问题讨论】:
【参考方案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_type
是 diesel::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
使用Deref
和DerefMut
,您可以为自己的类型实现取消引用,在本例中为PgDbConn
。现在,您可以写*conn
从您的PgDbConn
获得diesel::PgConnection
。但是,您需要对diesel::PgConnection
的引用。要获得引用,您必须再次引用取消引用的PgDbConn
,因此最终结果是&*conn
。
【讨论】:
非常感谢您提供详细而相关的答案! 在火箭方面更好的解决方案是直接在#guard_type
上实现diesel::Connection
,这样用户就不必进行&*conn
deref 转换。这似乎是一个很常见的混淆来源。为此,在他们的错误跟踪器中填写一个问题可能是有意义的。以上是关于在 rust 中引用和取消引用数据库连接的主要内容,如果未能解决你的问题,请参考以下文章
当取消处理程序引用自身时,在 -dealloc 中取消 XPC 连接