Rust中如何实现依赖泛型标记trait的Foo泛型包装器?
解决方案
核心问题在于编译器无法自动从FooWrapper<F>: FooMarker<T>推导出F: FooMarker<T>,我们需要在do_foo方法的约束里明确这个关联,同时满足原trait Foo的要求。
写法一:保留原约束并补充推导条件
修改FooWrapper的Foo实现,给do_foo方法的where子句添加F: FooMarker<T>约束:
struct FooWrapper<F> { inner_foo: F } // 假设do_extra_stuff是已定义的扩展函数 fn do_extra_stuff() { // 自定义扩展逻辑 } impl<F: Foo> Foo for FooWrapper<F> { fn do_foo<T>(&mut self, x: &T) where Self: FooMarker<T>, // 保留原trait要求的约束 F: FooMarker<T> // 明确告知编译器inner_foo的约束 { do_extra_stuff(); self.inner_foo.do_foo(x); } fn do_bar(&mut self) { self.inner_foo.do_bar(); } } impl<T, F: FooMarker<T>> FooMarker<T> for FooWrapper<F> {}
写法二:利用实现逻辑简化约束
因为我们的FooMarker<T>实现逻辑是当F: FooMarker<T>时,FooWrapper<F>必然满足FooMarker<T>,因此可以直接用更强的约束替代原trait要求的约束,编译器会自动验证其合法性:
struct FooWrapper<F> { inner_foo: F } fn do_extra_stuff() { // 自定义扩展逻辑 } impl<F: Foo> Foo for FooWrapper<F> { fn do_foo<T>(&mut self, x: &T) where F: FooMarker<T> { do_extra_stuff(); self.inner_foo.do_foo(x); } fn do_bar(&mut self) { self.inner_foo.do_bar(); } } impl<T, F: FooMarker<T>> FooMarker<T> for FooWrapper<F> {}
两种写法都能解决编译问题:
- 第一种严格遵循原
trait的约束声明,同时补充编译器需要的推导条件 - 第二种利用自定义
FooMarker的实现逻辑,简化约束的同时保证合法性
内容的提问来源于stack exchange,提问作者Locke
相关产品推荐
相关产品推荐

