Rust 类型参数的使用寿命

Rust 类型参数的使用寿命,rust,lifetime,type-parameter,Rust,Lifetime,Type Parameter,我正在处理一个简单的复数示例,并尝试实现ref-value/value-ref操作,如下所示: use std::ops::*; #[derive(Clone, PartialEq)] pub struct Complex<T: Sized + Clone> { pub re: T, pub im: T, } // Ref-Ref Multiplication impl<'a, 'b, T: Sized + Clone> Mul<&'b

我正在处理一个简单的复数示例,并尝试实现ref-value/value-ref操作,如下所示:

use std::ops::*;

#[derive(Clone, PartialEq)]
pub struct Complex<T: Sized + Clone> {
    pub re: T,
    pub im: T,
}

// Ref-Ref Multiplication
impl<'a, 'b, T: Sized + Clone> Mul<&'b Complex<T>> for &'a Complex<T>
where
    T: Add<T, Output = T>,
    T: Sub<T, Output = T>,
    &'a T: Add<&'b T, Output = T>,
    &'a T: Mul<&'b T, Output = T>,
    &'a T: Sub<&'b T, Output = T>,
{
    type Output = Complex<T>;
    fn mul(self, rhs: &'b Complex<T>) -> Complex<T> {
        panic!("// Details irrelevant")
    }
}

// Ref-Value Multiplication
impl<'a, 'b, T: Sized + Clone> Mul<Complex<T>> for &'a Complex<T>
where
    T: 'static,
    T: Add<T, Output = T>,
    T: Sub<T, Output = T>,
    &'a T: Add<&'b T, Output = T>,
    &'a T: Mul<&'b T, Output = T>,
    &'a T: Sub<&'b T, Output = T>,
{
    type Output = Complex<T>;
    fn mul(self, rhs: Complex<T>) -> Complex<T> {
        let t = &rhs;
        self.mul(t)
    }
}
使用std::ops::*;
#[派生(克隆,部分Q)]
pub结构复合体{
酒吧:T,
酒吧im:T,
}
//Ref-Ref乘法
impl Mul,
&“a:T:Mul复合体{
惊慌失措!(“//细节无关”)
}
}
//参考值乘法
一个复合体的impl Mul
哪里
T:静态,
T:加上,
T:Sub,

&'a T:Add正如Peter Hall在评论中所建议的那样,最简单的解决方案是为复杂类型派生
Copy
,并对值执行操作。对于ref-ref实现和ref-val实现,您可以简单地取消引用并使用val实现

如果你想让你开始的方法起作用,你需要更高的等级特征界限:

use std::ops::*;

#[derive(Clone, PartialEq)]
pub struct Complex<T: Clone> {
    pub re: T,
    pub im: T,
}

// Ref-Ref Multiplication
impl<'a, 'b, T: Clone> Mul<&'b Complex<T>> for &'a Complex<T>
where
    T: Add<T, Output = T>,
    T: Sub<T, Output = T>,
    &'a T: Add<&'b T, Output = T>,
    &'a T: Mul<&'b T, Output = T>,
    &'a T: Sub<&'b T, Output = T>,
{
    type Output = Complex<T>;
    fn mul(self, rhs: &'b Complex<T>) -> Complex<T> {
        Complex {
            re: &self.re * &rhs.re - &self.im * &rhs.im,
            im: &self.re * &rhs.im + &self.im * &rhs.re,
        }
    }
}

// Ref-Value Multiplication
impl<'a, T: Clone> Mul<Complex<T>> for &'a Complex<T>
where
    T: Add<T, Output = T>,
    T: Sub<T, Output = T>,
    &'a T: for<'b> Add<&'b T, Output = T>,
    &'a T: for<'b> Mul<&'b T, Output = T>,
    &'a T: for<'b> Sub<&'b T, Output = T>,
{
    type Output = Complex<T>;
    fn mul(self, rhs: Complex<T>) -> Complex<T> {
        let t = &rhs;
        self.mul(t)
    }
}

内置的数字类型使用一个数组来实现这些排列。手动操作时,我将从两个值相乘的情况开始,而不是任何引用,并确保您的
复杂结构是
Copy

impl<T: Copy> Mul<Complex<T>> for Complex<T>
where
    T: Add<T, Output = T>,
    T: Sub<T, Output = T>,
    T: Mul<T, Output = T>,
{
    type Output = Complex<T>;
    fn mul(self, rhs: Complex<T>) -> Complex<T> {
        unimplemented!()
    }
}

您可能应该为
复杂
派生
克隆
,然后为
复杂
而不是
复杂
实现ops。这不仅仅是绕过了这个问题,它通常比这样一个小结构的引用要快。我甚至更进一步,为复数类型派生
Copy
,这样你甚至不必显式克隆。@SvenMarnach谢谢,这正是我想要写的!(
Copy
,而不是
Clone
):)您对
和'at
的约束是不必要的。最后,您将把
T
从另一个
Complex
中复制出来,并将它们移动到一个新的
Complex
。这里没有引用原始
t
的方法,因此没有必要考虑对
&t
进行操作。您看起来想要impl。这里不需要HRTB。这里所有的生命周期都是在调用
mul
方法时知道的。是的,HRTB是我所需要的。我已经忘记他们很久了。谢谢只是注意到我已经完成了有价值的事情。只是没有显示出这是微不足道的,我有理由不这样做(在回答问题评论时提到)。@PeterHall我不这么认为。当时不知道局部变量
t
的生存期。@Nim我添加了一种更简洁的编写特征边界的方法。克隆/复制方法是我在其他实现中看到的,也是我知道的。我有几个理由想避免这种情况,主要是如果T是一个更复杂的结构(例如,任意精度浮点);在这种情况下,ref操作会更快。还有一个简单的问题,正如你提到的,我不能返回对t的引用;你能详细说明一下吗?T不可能是包含T的引用的结构吗?类似于
struct A)
我假设这就是我的代码没有编译的原因,除非我弄错了。@Nim如果要返回引用,它需要指向调用
mul()
方法之前存在的值;您不能返回对在方法中计算的新值的引用。@SvenMarnach这就是我认为发生错误的原因。我需要一些澄清,因为它的措辞是作为一般无法返回的引用,因此我的例子。只是想确保我没有错过一些微妙的东西,除了生命太短暂而无法接受之外。
impl<T: Copy> Mul<Complex<T>> for Complex<T>
where
    T: Add<T, Output = T>,
    T: Sub<T, Output = T>,
    T: Mul<T, Output = T>,
{
    type Output = Complex<T>;
    fn mul(self, rhs: Complex<T>) -> Complex<T> {
        unimplemented!()
    }
}
impl<'a, T: Copy> Mul<Complex<T>> for &'a Complex<T>
where
    T: Add<T, Output = T>,
    T: Sub<T, Output = T>,
    T: Mul<T, Output = T>,
{
    type Output = Complex<T>;
    fn mul(self, rhs: Complex<T>) -> Complex<T> {
        (*self).mul(rhs)
    }
}

impl<'a, T: Copy> Mul<&'a Complex<T>> for Complex<T>
where
    T: Add<T, Output = T>,
    T: Sub<T, Output = T>,
    T: Mul<T, Output = T>,
{
    type Output = Complex<T>;
    fn mul(self, rhs: &'a Complex<T>) -> Complex<T> {
        self.mul(*rhs)
    }
}

impl<'a, 'b, T: Copy> Mul<&'a Complex<T>> for &'b Complex<T>
where
    T: Add<T, Output = T>,
    T: Sub<T, Output = T>,
    T: Mul<T, Output = T>,
{
    type Output = Complex<T>;
    fn mul(self, rhs: &'a Complex<T>) -> Complex<T> {
        (*self).mul(*rhs)
    }
}