Rust 泛型函数接受原始整数和地毯整数

问题描述 投票:0回答:2

我正在尝试编写一个对整数进行操作的通用函数,它可以接受原始整数或多精度整数(通过

rug
)。棘手的一点是,对 rug
Integer
的引用具有惰性算术运算,即 返回不完整的类型,直到转换为整数。所以我认为像下面这样的东西会起作用,但我似乎无法正确设置生命周期(并且 rust-analyzer 在帮助方面并不是非常冗长):

use rug::Integer;
use std::ops::Mul;

fn mymul<T, S>(x: &T, y: &T) -> T
where
    T: 'static + From<S>,
    for<'a> &'a T: Mul<&'a T, Output = S>,
{
    T::from(x * y)
}

fn main() {
    let x: u64 = 3847381;
    let y: u64 = 28478195;
    let rug_x = Integer::from(x);
    let rug_y = Integer::from(y);
    println!("{} == {:?}", mymul(&x, &y), mymul(&rug_x, &rug_y));
}

有错误

error[E0308]: mismatched types
  --> src/main.rs:22:43
   |
22 |     println!("{} == {:?}", mymul(&x, &y), mymul(&rug_x, &rug_y));
   |                                           ^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected struct `integer::arith::MulIncomplete<'a>`
              found struct `integer::arith::MulIncomplete<'_>`
note: the lifetime requirement is introduced here
  --> src/main.rs:12:31
   |
12 |     for<'a> &'a T: Mul<&'a T, Output = S>,
   |                               ^^^^^^^^^^

知道如何正确地做这类事情吗?

rust biginteger trait-bounds
2个回答
0
投票

问题是您没有将输入生命周期(

x
y
)连接到乘法产生的生命周期,您可以通过引入生命周期轻松地做到这一点,这也允许放宽对
'static
的限制
T

fn mymul<'a, T, S>(x: &'a T, y: &'a T) -> T
where
    T: From<S> + 'a,
    &'a T: Mul<&'a T, Output = S>,
{
    (x * y).into()
}

0
投票

此版本按预期编译。

fn mymul<'a, T, S>(x: &'a T, y: &'a T) -> T
where
    T: 'static + From<S>,
    &'a T: Mul<&'a T, Output = S>,
{
    T::from(x * y)
}

我相信不同之处在于,在你的定义中,对于每个生命周期

'a
,类型
S
必须是相同的类型。但事实并非如此,因为
S
会根据生命周期而变化,如 impl 的输出所示:
type Output = MulIncomplete<'a>

在我编写的版本中,

S
允许根据生命周期而变化
'a

© www.soinside.com 2019 - 2024. All rights reserved.