我有一个配置结构体,长这样:
struct Conf {
list: Vec<String>,
}
实现内部正在填充list
成员,但现在我决定将这个任务委托给另一个对象。所以我现在有:
trait ListBuilder {
fn build(&self, list: &mut Vec<String>);
}
struct Conf<T: Sized + ListBuilder> {
list: Vec<String>,
builder: T,
}
impl<T> Conf<T>
where
T: Sized + ListBuilder,
{
fn init(&mut self) {
self.builder.build(&mut self.list);
}
}
impl<T> Conf<T>
where
T: Sized + ListBuilder,
{
pub fn new(lb: T) -> Self {
let mut c = Conf {
list: vec![],
builder: lb,
};
c.init();
c
}
}
看起来这个方案很好,但是现在每次我使用Conf
时,都必须进行更改:
fn do_something(c: &Conf) {
// ...
}
变成
fn do_something<T>(c: &Conf<T>)
where
T: ListBuilder,
{
// ...
}
由于我有许多这样的功能,所以这种转换很痛苦,特别是因为大多数
Conf
类的用法并不关心ListBuilder
——它是一个实现细节。我担心如果我给Conf
添加另一个泛型类型,现在我必须回去在所有地方添加另一个泛型参数。有没有办法避免这种情况?我知道我可以使用闭包来代替列表构建器,但我有一个额外的限制,我的
Conf
结构体需要是Clone
的,而实际的构建器实现更复杂,并且在构建器中有几个函数和一些状态,这使得闭包方法难以处理。
Sized
;这是默认设置。 - Shepmaster