为何已在其他impl块添加trait bounds,仍需重复添加?
为什么不同impl块需要重复添加trait bounds?
这是个很典型的Rust新手疑问,我来给你掰扯清楚:
Rust里的每个impl块都是完全独立的实现单元,它们之间不会共享trait约束。也就是说,你在第一个impl里给T加的Div<Output = T> + Copy bounds,只会作用于这个块里定义的方法(new和baz),对其他impl块没有任何“继承”效果。
结合你的代码具体分析
看你实现Mul trait的那个impl块:
impl<T> Mul for Foo<T> where T: Mul<Output = T>, { type Output = Foo<T>; fn mul(self, other: Foo<T>) -> Foo<T> { Foo::new(self.bar * other.bar) } }
这里面有两个关键需求:
self.bar * other.bar需要T实现Mul<Output=T>,你已经加了这个约束,没问题;- 调用
Foo::new的时候,new方法要求T必须满足Div<Output=T> + Copy——但这个约束只在第一个impl块里定义了,当前这个impl块并不知道,所以你其实还得把这两个约束也加到当前的where从句里,不然编译器会报错。
为什么Rust要这么设计?
这其实是Rust“明确性优先”设计哲学的体现:
- 每个
impl块的约束都清晰可见,不用读者去翻其他impl块找隐含依赖; - 编译器可以独立检查每个
impl块的合法性,避免因为跨impl的隐含约束导致复杂的编译错误; - 允许你为同一个类型在不同的约束下实现不同的逻辑(比如给
Foo<T>在T: Ord时实现一个方法,在T: PartialEq时实现另一个,互相不干扰)。
简单说就是:Rust不做“默认共享”这种假设,一切约束都要明明白白写出来,虽然看起来有点繁琐,但能避免很多隐蔽的bug~
内容的提问来源于stack exchange,提问作者HiDefender
相关产品推荐
相关产品推荐

