Rust泛型结构体保持通用实现但调用特定数组trait方法报错如何解决?
错误原因
Rust 编译器在编译泛型代码时,只会基于你声明的泛型约束做检查,不会主动推导「所有实现了A的T对应的[T;2]都实现了DivArray」这个逻辑,哪怕你实际上只给u32、u64实现了A trait也不行。你当前只给[u32;2]和[u64;2]写了DivArray的实现,但是没有在C<T>的泛型约束中声明[T; 2]满足DivArray的实现要求,因此编译不通过。
另外你定义的DivArray trait上的生命周期参数'a没有被任何字段/方法使用,属于冗余参数,也会额外增加约束匹配的难度。
解决方法
方案1:补充泛型约束(稳定版可用,无额外特性依赖)
直接在C<T>的impl块中补充约束,明确要求[T; 2]实现了对应入参类型的DivArray trait即可,修改后的代码如下:
use core::marker::PhantomData; use num_traits::Zero; pub trait A: Zero + Copy {} impl A for u32{} impl A for u64{} // 移除冗余的生命周期参数'a pub trait DivArray<Rhs>: Sized + Copy { type Output; fn div_array( self, denominator: Rhs, ) -> Result<Self::Output, ()>; } impl<Rhs: Into<Rhs>> DivArray<Rhs> for [u32; 2] { type Output = [u32; 2]; fn div_array( self, denominator: Rhs, ) -> Result<Self::Output, ()> { unimplemented!(); } } impl<Rhs: Into<Rhs>> DivArray<Rhs> for [u64; 2] { type Output = [u64; 2]; fn div_array( self, denominator: Rhs, ) -> Result<Self::Output, ()> { unimplemented!(); } } pub struct C<T>{ _phantom: PhantomData<T> } // 补充约束:[T;2]实现了入参为u64的DivArray,输出为[T;2] impl<T: A> C<T> where [T; 2]: DivArray<u64, Output = [T; 2]> { pub fn something(&self) { let arr = [T::zero(); 2]; arr.div_array(1u64); } }
这个方案不需要额外依赖不稳定特性,完全符合Rust稳定版的语法规则,同时保留了你对[u32;2]和[u64;2]的特化实现逻辑,C<T>也只会允许T为u32、u64的实例化,完全符合你的需求。
方案2:使用特化特性(仅nightly可用)
如果你可以接受使用nightly版本的Rust,可以开启min_specialization特性,先给所有T:A的[T;2]写默认实现,再单独给u32、u64写特化实现,不过这种写法会引入不稳定特性依赖,不建议生产环境使用。
内容的提问来源于stack exchange,提问作者Margareth Reena
相关产品推荐
相关产品推荐

