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

Rust中如何不克隆&str转为&String包装的自定义结构体?

解决方案

要避免克隆&str,核心是让包装类型无需持有String的所有权,或者新增一个支持借用的包装类型适配trait。下面提供两种可行方案:

方案一:将ParentObjectId改为泛型结构体

调整结构体定义,让它可以持有任意实现AsRef<str>的类型(包括&str和String),同时更新trait实现兼容泛型参数:

// 泛型版本的包装结构体
pub struct ParentObjectId<S>(pub S)
where
    S: AsRef<str>;

// 泛型实现IGetByField trait
impl<'r, S> IGetByField<Object, ParentObjectId<S>> for ObjectDao<'r>
where
    S: AsRef<str>,
{
    fn get_by_field(&self, parent_object_id: &ParentObjectId<S>) -> Vec<Org> {
        let connection = &mut unpool!(self.pool.get());
        // 通过as_ref()获取&str
        DB::get_object_by_parent_id(connection, parent_object_id.0.as_ref())
    }
}

调用时直接传入&str,无需克隆:

let some_parent_id: &str = "some_id";
// 直接用&str构造ParentObjectId,无克隆操作
let object = object_dao.get_by_field(&ParentObjectId(some_parent_id));

该方案兼容原有String场景和新的&str场景,无需额外定义新类型。

方案二:新增借用型包装结构体

如果不想修改原有ParentObjectId的定义,可以新增一个仅持有&str引用的包装类型,并为它单独实现trait:

// 新增的借用型包装结构体
pub struct ParentObjectIdRef<'a>(pub &'a str);

// 为借用类型实现IGetByField trait
impl<'r, 'a> IGetByField<Object, ParentObjectIdRef<'a>> for ObjectDao<'r> {
    fn get_by_field(&self, parent_object_id: &ParentObjectIdRef<'a>) -> Vec<Org> {
        let connection = &mut unpool!(self.pool.get());
        DB::get_object_by_parent_id(connection, parent_object_id.0)
    }
}

调用时使用新的借用类型:

let some_parent_id: &str = "some_id";
// 用&str构造ParentObjectIdRef,无克隆
let object = object_dao.get_by_field(&ParentObjectIdRef(some_parent_id));

该方案适合需要保留原有结构体定义,仅新增借用场景的情况。

内容的提问来源于stack exchange,提问作者thomasmost

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 17:03:24