Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
(Rust)是否有一种方法可以为过载的操作员自动借用?_Rust - Fatal编程技术网

(Rust)是否有一种方法可以为过载的操作员自动借用?

(Rust)是否有一种方法可以为过载的操作员自动借用?,rust,Rust,我试图在Rust中实现一个基本的多项式类型,使用重载运算符进行数学运算。到目前为止,我可以通过重载操作符来实现加法、减法等基本操作。问题是,我希望通过引用获取操作数,以避免不必要的复制。即。 : impl ops::Add for &Polynomial { type Output = Polynomial; fn add(self, other: Self) -> Polynomial { let mut result = self.clone()

我试图在Rust中实现一个基本的多项式类型,使用重载运算符进行数学运算。到目前为止,我可以通过重载操作符来实现加法、减法等基本操作。问题是,我希望通过引用获取操作数,以避免不必要的复制。即。 :

impl ops::Add for &Polynomial {
    type Output = Polynomial;
    fn add(self, other: Self) -> Polynomial {
        let mut result = self.clone();
        for (power, coeff) in other.coefficients.iter().enumerate() {
            result.add_coeff(power, *coeff);
        }
        result
    }
}
impl ops::Sub for &Polynomial {
    //  Implementation
    //  ...
}
impl ops::Mul for &Polynomial {
    //  Implementation
    //  ...
}
//  Etc.

这与预期的一样有效,但是它强制用户每次都显式借用操作数,随着表达式变得更复杂,可读性会降低 :

let (quotient, remainder) = p2.div_rem(&p1);

assert_eq!(&(&quotient * &p1) + &remainder, p2);

//  Even worse example found on the internet.
//  Note that you need to explicitly borrow each and every intermediate result :
let result = &(&(&a * &b) + &(&c * &d)) / 2;
我想,如果我能写的话,它会更清晰易读,而不是最后两行 :

assert_eq!(quotient * p1 + remainder, p2);

let result = (a * b + c * d) / 2;
…让借款发生« 自动地 »(就像调用一个方法时一样,该方法将
&self
作为任何值的第一个参数 : 它是自动和隐式借用的,而无需显式借用)


然而,我不知道这是否可能,或者如何做到 ?

> AfAIK,不,没有简单的方法来做这件事,因为锈设计引用总是明确的,从不隐含的,这是因为两种设计选择(即避免了C++引用的相同设计问题,这是奇怪的)和必要性(由于借阅检查器)。
T,&T,&mut T T,*const T
。。。都是具有不同语义的不同类型,因此允许
impl-ops::Add-for&polymone
也适用于
polymone
,基本上意味着
impl-ops::Add-for&T
将自动实现
ops::Add
for
T
,这可能会导致非常奇怪且可能不安全的结果,尤其是如果相反的情况也是如此。那么
&mut
呢?
&mut T
是否会自动衰减为
&
,对借书本身的寿命有何影响


此外,在非
复制
值类型上实现
ops::Add
是非常奇怪的,因为运算符会导致其操作数移入-这肯定不是人们在大多数情况下使用
+

时所期望的。标准方法是为引用和值定义算术运算。这对于实现来说可能有点乏味(通常涉及宏以减少代码重复),但为API用户提供了最大的可用性

然后,用户可以编写外观规则的代码,而无需额外借用,但也可以在希望保留值供以后使用时选择借用(从而避免不必要的复制)。例如,使用
num_bigint
板条箱,所有这些工作:

    assert!(BigUint::from(1u8) + BigUint::from(1u8) == BigUint::from(2u8));
    assert!(&BigUint::from(1u8) + &BigUint::from(1u8) == BigUint::from(2u8));
    assert!(BigUint::from(1u8) + &BigUint::from(1u8) == BigUint::from(2u8));
    assert!(&BigUint::from(1u8) + BigUint::from(1u8) == BigUint::from(2u8));

是的,在这种情况下,理论理想(“我想要
+
-
关于
多项式的
”)会冲向实用(“但它们不是
复制
,所以很奇怪”)和Rust,作为一种低级语言,落在这种二分法的实用方面。谢谢你的回答。然而,我不确定我是否理解你的最后一段。当人们添加两个值时,即
让c=a+b
他们期望值
a
b
在操作后仍然可用,并且不会被使用(这样您也可以在同一表达式中使用相同的值两次,即
让c=a*a;
),但我不明白为什么它会排除非复制类型,如果我们可以通过引用将值提供给运算符 ? 事实上,当我看到常见运算符(即+,-,*,/,%)一开始就没有引用时,我感到很惊讶,因为这个确切的原因。此外,实现ops::Add-on非复制值类型非常奇怪,由于运算符导致其操作数被移入-这绝对不是人们在大多数情况下使用+时所期望的事实并非如此,bigint板条箱往往同时实现这两种功能,是的,
+
-
确实可以移动东西。()请注意,这是一个非复制的函数,它实现了
Add
,通过值获取LHS,通过引用获取RHS。@user4815162342实现这两个函数并没有改变我所说的,它仍然让它变得奇怪,因为通常人们希望在进行求和或减法后两个操作数仍然可用。在大多数人的心目中,他们不是破坏性的操作员,他们本能地期望他们的行为就像他们是根据参考文献定义的一样。