suppose we have a wrapper type,这个类型约束了T必须实现 Debug
struct Wrapper<T>
where T: std::fmt::Debug
{
pub inner: T
}
假如有个方法将Wrapper作为参数传入
// because Wrapper take T as generic type, so the method that
// take Wrapper as parameter should also fulfil the constraint that
// T must implement std::fmt::Debug, but actually we don't care
fn take_wrapper<T>(w: Wrapper<T>) -> T
where T:std::fmt::Debug {
w.inner
}
take_wapper也必须加上这个约束,这里就会产生一个传播性,使用起来很麻烦,对于这种情况,我们可以采用laterBound
在定义Wrapper结构体的的时候不加约束,但是将inner类型作为private字段
// so we can use later bound the solve this problem
// we remove the where clause on struct and make inner private
pub struct LaterBoundWrapper<I> {
inner: I
}
提供一个工厂方法
impl <I> LaterBoundWrapper<I> {
// and we add constraint on new method, that means, whenever we want a Wrapper
// we have to create it through our factory method, and that will make sure
// only object that implement std::fmt::Debug can be used
pub fn new(d: I) -> Self
where I: std::fmt::Debug
{
LaterBoundWrapper {
inner: d
}
}
// we have to add an inspect function here
pub fn inspect(&self) where I: std::fmt::Debug {
println!("inspect inner {:?}", self.inner);
}
}
这样当接收 LaterBoundWrapper<T>
的时候就不需要再做泛型约束了,但是由于inner变成了一个private方法,同时此时的T没有了 Debug trait的约束,就需要新增一个inspect方法,也就是要将 LaterBoundWrapper 内聚
// we can remove the constraint on the take_later_bound_wrapper now
pub fn take_later_bound_wrapper<T>(w: LaterBoundWrapper<T>) {
// we can't debug here, as we don't know if inner is Debug
// println!("{:?}", w.inner);
w.inspect();
}