重载具有Rust特征的所有结构的运算符

重载具有Rust特征的所有结构的运算符,rust,Rust,我正在尝试使用traits和操作符重载在Rust中实现C++风格的表达式模板。我一直在尝试为每个表达式模板结构重载“+”和“*”。编译器抱怨Add和Mul特性实现: error[E0210]:类型参数'T'必须用作某些本地类型(例如'MyStruct')的类型参数 -->src/main.rs:32:6 | 32 | T的简单添加{ |^type参数“T”必须用作某些本地类型的类型参数 | =注意:只有当至少一种实现外部特征的类型是本地类型时,才可能实现外部特征 =注意:类型参数只能实现当前板条

我正在尝试使用traits和操作符重载在Rust中实现C++风格的表达式模板。我一直在尝试为每个表达式模板结构重载“+”和“*”。编译器抱怨
Add
Mul
特性实现:

error[E0210]:类型参数'T'必须用作某些本地类型(例如'MyStruct')的类型参数
-->src/main.rs:32:6
|
32 | T的简单添加{
|^type参数“T”必须用作某些本地类型的类型参数
|
=注意:只有当至少一种实现外部特征的类型是本地类型时,才可能实现外部特征
=注意:类型参数只能实现当前板条箱中定义的特征
如果我试图为其实现特征的类型在没有我的板条箱的情况下是可构造的,但该类型是必须实现我定义的
HasValue
特征的泛型,则该错误是有意义的

代码如下:

use std::ops::{Add, Mul};

trait HasValue {
    fn get_value(&self) -> i32;
}

// Val

struct Val {
    value: i32,
}

impl HasValue for Val {
    fn get_value(&self) -> i32 {
        self.value
    }
}

// Add

struct AddOp<T1: HasValue + Copy, T2: HasValue + Copy> {
    lhs: T1,
    rhs: T2,
}

impl<T1: HasValue + Copy, T2: HasValue + Copy> HasValue for AddOp<T1, T2> {
    fn get_value(&self) -> i32 {
        self.lhs.get_value() + self.rhs.get_value()
    }
}

impl<T: HasValue + Copy, O: HasValue + Copy> Add<O> for T {
    type Output = AddOp<T, O>;
    fn add(&self, other: &O) -> AddOp<T, O> {
        AddOp {
            lhs: *self,
            rhs: *other,
        }
    }
}

// Mul

struct MulOp<T1: HasValue + Copy, T2: HasValue + Copy> {
    lhs: T1,
    rhs: T2,
}

impl<T1: HasValue + Copy, T2: HasValue + Copy> HasValue for MulOp<T1, T2> {
    fn get_value(&self) -> i32 {
        self.lhs.get_value() * self.rhs.get_value()
    }
}

impl<T: HasValue + Copy, O: HasValue + Copy> Mul<O> for T {
    type Output = MulOp<T, O>;
    fn mul(&self, other: &O) -> MulOp<T, O> {
        MulOp {
            lhs: *self,
            rhs: *other,
        }
    }
}

fn main() {
    let a = Val { value: 1 };
    let b = Val { value: 2 };
    let c = Val { value: 2 };

    let e = ((a + b) * c).get_value();

    print!("{}", e);
}
使用std::ops:{Add,Mul};
特质价值{
fn get_值(&self)->i32;
}
//瓦尔
结构值{
值:i32,
}
Val的impl HasValue{
fn获取值(&self)->i32{
自我价值
}
}
//加
结构添加{
lhs:T1,
rhs:T2,
}
AddOp的impl HasValue{
fn获取值(&self)->i32{
self.lhs.get_值()+self.rhs.get_值()
}
}
对T的impl-Add{
类型输出=AddOp;
fn添加(&self,其他:&O)->AddOp{
阿多普{
lhs:*赛尔夫,
rhs:*其他,
}
}
}
//骡子
结构MulOp{
lhs:T1,
rhs:T2,
}
MulOp的impl HasValue{
fn获取值(&self)->i32{
self.lhs.get_值()*self.rhs.get_值()
}
}
对T的impl Mul{
类型输出=MulOp;
fn mul(&self,其他:&O)->MulOp{
穆洛普{
lhs:*赛尔夫,
rhs:*其他,
}
}
}
fn main(){
设a=Val{value:1};
设b=Val{value:2};
设c=Val{value:2};
设e=((a+b)*c).get_value();
打印!(“{}”,e);
}

想法?

试图为您的自定义类型定义特征
添加
,您正在执行以下操作:

impl<T: HasValue + Copy, O: HasValue + Copy> Add<O> for T {
    type Output = AddOp<T, O>;
    fn add(&self, other: &O) -> AddOp<T, O> {
        AddOp {
            lhs: *self,
            rhs: *other,
        }
    }
}
然后,您可以为您的
Val
类型添加一个整洁的
new()
方法:

impl Val {
    fn new(n: i32) -> Calculus<Val> {
        Calculus {
            calc: Val { value: n },
        }
    }
}

另一个解决方案是创建一个新的trait,让trait同时实现
HasValue
Copy
。然后可以为这个trait提供一个
Add
的全面实现。@MatthieuM。你确定吗?我不知道它如何解决这个问题,因为你仍然可以为已经存在的trait实现这个新的trait理论上,这是合理的,因为在为类型实现超级特征时,您必须知道该类型是否已经实现了任何子特征(从而可以决定是忽略超级特征默认实现还是引发错误)。在实践中,我不知道Rust是否允许它,以及它是否允许它选择哪个语义(忽略或错误)。
impl Val {
    fn new(n: i32) -> Calculus<Val> {
        Calculus {
            calc: Val { value: n },
        }
    }
}
fn main() {
    let a = Val::new(1);
    let b = Val::new(2);
    let c = Val::new(3);

    let e = ((a + b) * c).get_value();

    print!("{}", e);
}