簡體   English   中英

傳達類型參數的 Rust 生命周期

[英]Communicating Rust Lifetimes for Type Parameters

我正在研究一個簡單的復數示例,並嘗試按如下方式實現 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)
    }
}

ref-ref 實現有效,據我所知,它接受兩個不同生命周期的引用,並返回一個復雜的值類型。 參考值部分是我遇到問題的地方; 當我編譯時,錯誤是rhs壽命不夠長。 我相信我已經知道為什么會這樣了,那就是當返回值時 T 可以持有對 rhs 的引用(直接或間接),因此rhs超出范圍,但T仍然可以持有對它的引用。

我的問題是如何傳達T不會以某種形狀或形式引用rhs

關於我迄今為止嘗試過或看過的事情的一些說明:

  1. 更改了任一 Mul 實現的生命周期規范。
  2. 嘗試了生命周期繼承,但這指定了T持有的引用將至少與T一樣長,所以我認為我需要更多“至多”之類的東西。
  3. 查看了其他實現; 要么不實現這種情況,要么只是使用克隆來繞過問題。

正如 Peter Hall 在評論中所建議的,最簡單的解決方案是為您的復雜類型派生Copy ,並實現對值的操作。 對於 ref-ref 實現和 ref-val 實現,您可以簡單地取消引用引用並使用 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)
    }
}

在您的版本中,引用值實現中的生命周期'b由特征的用戶選擇。 由於用戶可以為'b使用任何生命周期,因此rhs需要靜態生命周期才能使您的代碼有效。 相反,您想要的是*'a T滿足任何給定生命周期'b的給定特征邊界,這正是 HRTB 的用途。

為第二個實現編寫 trait bound 的另一種不太重復的方法是:

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

內置數字類型使用實現這些排列。 手動完成,我將從您將兩個值相乘而不是任何引用的情況開始,並確保您的Complex結構是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!()
    }
}

請注意,您不需要對&T任何約束 - 無論如何您都無法返回對T引用,因此您將不得不復制它們,這就是我指定T: Copy

其余的實現現在很簡單,可以委托給最簡單的情況:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM