Rust嵌套类型场景下Deref强制转换不生效问题咨询
问题原因
Deref 强制转换只会在目标类型明确的场景下自动触发,泛型 trait 约束场景下编译器不会主动递归尝试解引用匹配 trait 实现,只会直接校验传入参数本身是否满足约束。你的代码中传入的参数是&Box<MyStruct<{integer}>>,该类型本身没有实现MyTrait,因此编译报错。
解决方案
在不修改foo(&data)调用语法的前提下,你可以添加一个覆盖所有可解引用到MyTrait实现类型的通用实现,让所有满足解引用条件的包装类型、引用类型自动实现MyTrait:
// 新增这段通用实现 impl<T, U> MyTrait for T where T: Deref<Target = U>, U: MyTrait, { fn bar(&self) { self.deref().bar() } }
完整可运行代码
use std::ops::Deref; struct MyStruct<T> { data: T } impl<T> Deref for MyStruct<T> { type Target = T; fn deref(&self) -> &Self::Target { &self.data } } pub trait MyTrait { fn bar(&self); } impl<T> MyTrait for MyStruct<T> { fn bar(&self) {} } // 新增的通用实现 impl<T, U> MyTrait for T where T: Deref<Target = U>, U: MyTrait, { fn bar(&self) { self.deref().bar() } } fn foo<T: MyTrait>(arg: T) { arg.bar(); } fn main() { let data = Box::new(MyStruct { data: 42 }); foo(&data); }
实现原理
添加上述通用实现后:
Box<MyStruct<T>>实现了Deref<Target = MyStruct<T>>,而MyStruct<T>实现了MyTrait,因此Box<MyStruct<T>>会自动获得MyTrait实现&Box<MyStruct<T>>实现了Deref<Target = Box<MyStruct<T>>>, 而Box<MyStruct<T>>已经实现了MyTrait,因此&Box<MyStruct<T>>也会自动获得MyTrait实现,刚好匹配foo的参数约束
注意事项
该通用实现会覆盖所有符合条件的类型,如果你后续需要为某个特定的指针/引用类型单独实现MyTrait会触发trait coherence冲突,如果没有这类定制需求,这是当前场景下最简洁的解决方案。
内容的提问来源于stack exchange,提问作者user2209008
相关产品推荐
相关产品推荐

