Rust通用函数接受原始整数和rug整数

huangapple go评论73阅读模式
英文:

Rust generic function accepting both primitive and rug integers

问题

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

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

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));
}
无法匹配的类型错误
  --&gt; 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
  --&gt; src/main.rs:12:31
   |
12 |     for<'a> &'a T: Mul<&'a T, Output = S>,
   |                               ^^^^^^^^^^
英文:

I'm trying to write a generic function that operates on integers, which can accept either primitive integers or multiprecision ones (via rug). The tricky bit is that references to rug Integers have lazy arithmetic operations, that return incomplete types until cast into an integer. So I thought something like the following would work, but I can't seem to get the lifetime setting correct (and rust-analyzer is not being super verbose in helping):

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

fn mymul&lt;T, S&gt;(x: &amp;T, y: &amp;T) -&gt; T
where
    T: &#39;static + From&lt;S&gt;,
    for&lt;&#39;a&gt; &amp;&#39;a T: Mul&lt;&amp;&#39;a T, Output = S&gt;,
{
    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!(&quot;{} == {:?}&quot;, mymul(&amp;x, &amp;y), mymul(&amp;rug_x, &amp;rug_y));
}

with error

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

Any idea how to do this sort of thing correctly?

答案1

得分: 3

以下是翻译好的部分:

正确的使用HRTB指定此函数的方式是:

fn mymul<T>(x: &T, y: &T) -> T
where
    for<'a> &'a T: Mul<&'a T>,
    for<'a> <&'a T as Mul<&'a T>>::Output: Into<T>,
{
    (x * y).into()
}
英文:

The right way to specify this function with HRTB is:

fn mymul&lt;T&gt;(x: &amp;T, y: &amp;T) -&gt; T
where
    for&lt;&#39;a&gt; &amp;&#39;a T: Mul&lt;&amp;&#39;a T&gt;,
    for&lt;&#39;a&gt; &lt;&amp;&#39;a T as Mul&lt;&amp;&#39;a T&gt;&gt;::Output: Into&lt;T&gt;,
{
    (x * y).into()
}

huangapple
  • 本文由 发表于 2023年7月28日 00:39:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76781828.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定