只要 `Integer::from` 有效,Rust 就会实现该功能

Rust implement the function as long as `Integer::from` works

我正在尝试实现 num_to_rug 函数,它将通用数字转换为 rug::Integer

(目的是调用Rug的素数测试,Integer::from(n).is_probably_prime)

这对于 u32u64 来说很容易做到,因为 Integer::from 是为他们实现的:

impl PrimeQ<u32> {
  fn num_to_rug(n: u32) -> Integer {
    Integer::from(n)
  }
}

impl PrimeQ<u64> {
  fn num_to_rug(n: u64) -> Integer {
    Integer::from(n)
  }
}

现在我想为任何类型实现此功能:

pub trait PrimeSieveTrait:
  AddAssign + SubAssign + MulAssign + DivAssign + integer::Roots + PrimInt + FromPrimitive {}
impl<T> PrimeSieveTrait for T
  where T:
    AddAssign + SubAssign + MulAssign + DivAssign + integer::Roots + PrimInt + FromPrimitive {}

如何修改下面的代码以便编译?

impl<T: ?> PrimeQ<T> {
  fn num_to_rug(n: T) -> Integer {
    Integer::from(n)
  }
}

如果你真的想使用 From<T> 特征,那么这不能表示为内联特征边界——你需要使用 where 子句来代替:

impl<T> PrimeQ<T>
where
    T: PrimeSieveTrait,
    Integer: From<T>,
{
    fn num_to_rug(n: T) -> Integer {
        Integer::from(n)
    }
}

一个更好的选择是使用 Into<Integer> trait,在这种情况下你只需要 T:

上的 trait bounds
impl<T: PrimeSieveTrait + Into<Integer>> PrimeQ<T> {
    fn num_to_rug(n: T) -> Integer {
        n.into()
    }
}

(我通常也会用 where 子句来写它,因为我发现它更具可读性。)

更一般地说,特征界限 U: From<T> 意味着 T: Into<U> 因为 blanket implementation in the standard library。这意味着在上面的第二个代码片段中使用特征绑定 T: Into<U> 可以使您的函数更通用,并且使用起来也更方便,因此它应该优于 From 特征绑定。