gpt4 book ai didi

rust - 在 Rust 中为所有具有特征的结构重载运算符

转载 作者:行者123 更新时间:2023-11-29 07:46:58 27 4
gpt4 key购买 nike

我正在尝试使用特征和运算符重载在 Rust 中实现 C++ 风格的表达式模板。我在尝试为每个表达式模板结构重载“+”和“*”时遇到困难。编译器提示 AddMul 特征实现:

error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
--> src/main.rs:32:6
|
32 | impl<T: HasValue + Copy, O: HasValue + Copy> Add<O> for T {
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter

如果我尝试为其实现特征的类型在没有我的 crate 的情况下是可构造的,但该类型是必须实现我定义的 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);
}

想法?

最佳答案

试图定义特征 Add对于您的自定义类型,您正在这样做:

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,
}
}
}

但是T: HasValue + Copy匹配任何实现特征的类型 HasValue , 并且这种类型可能没有在你的包中定义(例如,如果你为 HasValue 实现了 i32 )。作为Add也没有在你的 crate 中定义,Rust 提示说:例如通过定义 HasValue对于 i32 , 你也会重新定义 Add<i32>对于 i32 !

我的建议是将所有操作和值结构包装到一个通用结构中,并实现 AddMul为了它。这样,您就实现了 AddMul仅适用于您的 crate 中定义的简单类型,编译器很高兴。

类似的东西:

struct Calculus<T> {
calc: T,
}

impl<T: HasValue + Copy> HasValue for Calculus<T> {
fn get_value(&self) -> i32 {
self.calc.get_value()
}
}

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

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

然后你可以添加一个整洁的new() Val 的方法输入:

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);
}

Playground

关于rust - 在 Rust 中为所有具有特征的结构重载运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26518233/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com