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
相关产品推荐
相关产品推荐

