Rust中不依赖Copy trait实现泛型数学运算的Mul方法调用问题
Rust泛型平方函数报错原理说明
核心报错原因
你遇到的编译错误是Mul trait的定义和Rust方法调用自动解析规则共同作用的结果:
std::ops::Multrait的核心方法签名为fn mul(self, rhs: Rhs) -> Self::Output,接收器self为按值传递,调用该方法会直接消耗接收器的所有权。- Rust方法调用的自动解引用(autoderef)规则为:调用方法时编译器会优先匹配接收器原始类型的trait实现,匹配失败时会自动对接收器做解引用尝试,不会主动为接收器添加引用来匹配实现。
你的代码中仅约束了A: Mul<&'a A, Output = A>,即仅声明了「A类型本身可以和&'a A类型做乘法返回A」,未声明「&'a A类型可以和&'a A类型做乘法返回A」。当调用n.mul(n)时,n本身是&'a A类型,编译器找不到&'a A对应的Mul实现,就会自动将n解引用为*n(即A类型),此时刚好匹配上你声明的A的Mul实现。但调用(*n).mul(n)需要将*n按值传给self参数,会尝试move共享引用背后的数值,而A没有实现Copy trait,因此触发了E0507报错。
兼容无Copy类型的实现方案
只需要将trait约束从「A类型实现Mul」调整为「A的引用类型实现Mul」即可:
fn square_ref<'a, A>(n: &'a A) -> A where &'a A: Mul<&'a A, Output = A>, { n * n }
绝大多数大数库的数值类型都实现了引用版本的乘法运算,该实现不需要消耗数值所有权,也不需要Copy约束,可以同时兼容内置数值类型和自定义大数类型。
内容的提问来源于stack exchange,提问作者J. Dane
相关产品推荐
相关产品推荐

