I have a configuration struct that looks like this:
struct Conf {
list: Vec<String>,
}
The implementation was internally populating the list
member, but now I have decided that I want to delegate that task to another object. So I have:
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
}
}
That seems to work fine, but now everywhere that I use Conf
, I have to change it:
fn do_something(c: &Conf) {
// ...
}
becomes
fn do_something<T>(c: &Conf<T>)
where
T: ListBuilder,
{
// ...
}
Since I have many such functions, this conversion is painful, especially since most usages of the Conf
class don't care about the ListBuilder
- it's an implementation detail. I'm concerned that if I add another generic type to Conf
, now I have to go back and add another generic parameter everywhere. Is there any way to avoid this?
I know that I could use a closure instead for the list builder, but I have the added constraint that my Conf
struct needs to be Clone
, and the actual builder implementation is more complex and has several functions and some state in the builder, which makes a closure approach unwieldy.
Question&Answers:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…