You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 21:01:05