Rust如何实现支持引用相加的RefAddable trait?高阶约束为何不生效
问题2解答:原RefAddable不符合预期的原因
Rust中trait定义块后的where约束仅作用于该trait的实现阶段,仅代表「若要为某类型实现该trait,必须满足这些约束」,并不会把这些约束作为trait的能力承诺对外暴露。当你在泛型约束中写T: RefAddable时,编译器只会认为T实现了RefAddable空trait,不会自动推导得出&'a T满足Add<Output = T>的约束,所以需要你重复补充约束。
问题1解答:符合要求的RefAddable实现
要让T: RefAddable自动携带「两个&T相加可得T」的约束,只需要补充全覆盖实现(Blanket Implementation),让所有满足条件的类型自动实现RefAddable,就能把约束和trait绑定:
use std::ops::Add; trait RefAddable: Sized {} // 全覆盖实现:只要满足引用相加的约束,就自动实现RefAddable impl<T> RefAddable for T where T: Sized, for<'a> &'a T: Add<&'a T, Output = T>, {}
使用示例
#[derive(Debug, PartialEq)] struct Foo(i32); // 为Foo的引用实现Add impl<'a> Add for &'a Foo { type Output = Foo; fn add(self, rhs: Self) -> Self::Output { Foo(self.0 + rhs.0) } } // 无需手动实现RefAddable,全覆盖实现会自动处理 struct Bar<T: RefAddable> { inner: T, } impl<T: RefAddable> Bar<T> { fn combine(&self, a: &T, b: &T) -> T { // 直接编译通过,不需要额外补充约束 a + b } } fn main() { let bar = Bar { inner: Foo(0) }; assert_eq!(bar.combine(&Foo(1), &Foo(2)), Foo(3)); }
如果希望更直观地把约束写在trait定义中,也可以直接把约束放到trait的超类约束块:
trait RefAddable: Sized where for<'a> &'a Self: Add<&'a Self, Output = Self>, {} // 全覆盖实现保持不变即可
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

