在 Rust 中,如何限制泛型 T 以允许模数?

Bri*_*ler 4 restriction modulo bounds type-parameter rust

作为锻炼练习,我目前正在尝试根据值是否为偶数来过滤迭代器,以生成新的迭代器。

我的功能目前看起来像:

pub fn evens<T>(iter: impl Iterator<Item = T>) -> impl Iterator<Item = T>
    where T: std::ops::Rem<Output = T>
{
    iter.filter(|x| x % 2 != 0)
}
Run Code Online (Sandbox Code Playgroud)

操场

但这不会编译,因为:

pub fn evens<T>(iter: impl Iterator<Item = T>) -> impl Iterator<Item = T>
    where T: std::ops::Rem<Output = T>
{
    iter.filter(|x| x % 2 != 0)
}
Run Code Online (Sandbox Code Playgroud)

但是,我知道我不能简单地将其更改为

error[E0369]: cannot mod `&T` by `{integer}`
 --> src/lib.rs:4:23
  |
4 |     iter.filter(|x| x % 2 != 0)
  |                     - ^ - {integer}
  |                     |
  |                     &T
  |
help: consider further restricting this bound
  |
2 |     where T: std::ops::Rem<Output = T> + std::ops::Rem<Output = {integer}>
  |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

操场

因为这无法编译:

pub fn evens<T>(iter: impl Iterator<Item = T>) -> impl Iterator<Item = T>
    where T: std::ops::Rem<Output = T> + std::ops::Rem<Output = {integer}>
{
    iter.filter(|x| x % 2 != 0)
}
Run Code Online (Sandbox Code Playgroud)

我隐约知道一些“Num”特征,但 exercism 似乎不接受需要通过 Cargo.toml 导入依赖项的答案,因此我正在寻找本机/内置解决方案。

我有什么想法可以使这项工作?

(PS 我现在发现我误解了这个练习,其中“偶数”描述了枚举索引,而不是值……但没关系。我仍然想知道这是否/如何使其起作用。 )

orl*_*rlp 5

没有第三方库的最简单方法是将常量T显式转换为:

use core::convert::TryFrom;

pub fn evens<T>(iter: impl Iterator<Item = T>) -> impl Iterator<Item = T>
    where T: Eq + Copy + std::ops::Rem<Output=T> + TryFrom<i32>
{
    let zero = T::try_from(0).ok().unwrap();
    let two = T::try_from(2).ok().unwrap();
    iter.filter(move |x| *x % two != zero)
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以改用 `From&lt;u8&gt;`,它为除 `i8` 之外的所有整数类型实现。 (2认同)
  • @Netwave:但是没有标准类型会导致 `try_from(0u8)` 或 `try_from(2u8)` 失败,所以你应该是安全的。 (2认同)