使用postgres_types::Json时如何避免克隆操作?
避免克隆:tokio-postgres中Json类型复用结构体的方案
你不需要克隆整个Device结构体,核心思路是让postgres_types::Json持有结构体的引用而非所有权。
具体实现
postgres_types::Json<T>的泛型参数T只要实现了serde::Serialize即可,而Rust会自动为引用类型&Device实现Serialize(前提是Device本身已经derive了Serialize)。所以可以直接将Json::<Device>(device.clone())替换为Json::<&Device>(device),这样Json只会持有device的引用,不会转移所有权,你后续依然可以正常使用device.country等字段。
修改后的代码片段:
pub async fn user_exists_ipv4( pool: &Pool, ip: IpAddr, device: &Device, ) -> Result<Option<Uuid>, String> { let conn = get_connection(pool).await?; let country = &device.country[..]; let result = conn .query( FETCH_USER_QUERY_FOR_V4, &[ &ip.to_string(), &Json::<&Device>(device), // 改为包裹结构体引用 &country.to_string(), ], ) .await? // 后续仍可正常使用device的任意字段 ... }
原理说明
当你使用Json::<&Device>(device)时,Json内部存储的是&Device而非结构体副本。tokio-postgres在序列化参数时,会通过这个引用读取Device的数据,不会影响原结构体的生命周期(这里函数参数device的引用生命周期覆盖整个函数,完全满足查询执行的需求)。
这种方案完全避免了克隆操作,没有任何性能开销,是最理想的解决方式。
内容的提问来源于stack exchange,提问作者Lefevre Victor
相关产品推荐
相关产品推荐

